2013-03-10 44 views
1

我有两个问题。我有一个包含包含.txt文件的子文件夹的文件夹。该TXT文件格式的使用sed将文件名的一部分提取到变量中

{title.of.a.book}.V{4 digit year}.{4 digit issue}.txt 

例如

to.kill.a.mockingbird.V1960.0001.txt 

我要拉出来的信息三个部分:

  1. 标题(用空格代替周期)例如:杀一只嘲鸟
  2. 卷号例如:1960
  3. 发行编号例如:0001

这是我到目前为止已经写

for file in $(find /home/user/books -type f -name '*.txt') 
do 
    name=$(echo "$file"|sed -e 's/^\(.*\).V.*txt$/\1/') 
    volume=$(echo "$file"|sed -e 's/^.*V\(\d{4}\).*$/\1/') 
    issue=$(echo "$file"|sed -e 's/^.*\(\d{4}\).txt$/\1/') 
    echo "$name" "$volume" "$issue" 
done 
  1. 如何拉出3个信息给独立的变量
  2. 如何更换.用空格

我无法决定是先重命名文件(重命名为s/./ /g) - 或者之后重命名$name

名称变量打印正确,但成交量及发行数量的变量只是打印的文件名了...

回答

0

solution通过speakr可能是最好的,但我还是老派和类似sed

您可以在单个-e参数中提供多个命令给sed,该参数以分号分隔或多个-e参数;我更多地使用后者。我还会清除find的名称以删除主要路径。然后,您需要决定是否使用扩展的正则表达式,而且您需要使用的是一致的。

使用GNU sed 4.4.2(©2012),我无法获得\d表示法来识别数字;这里可能有些愚蠢的东西。

没有扩展正则表达式(将与sed非GNU版本的工作):

for file in $(find /home/user/books -type f -name '*.txt') 
do 
    base=$(basename $file .txt) 
    name=$( echo "$base" | sed -e 's/^\(.*\).V.*$/\1/' -e 's/\./ /g') # replace dots 
    volume=$(echo "$base" | sed -e 's/^.*V\([0-9]\{4\}\).*$/\1/') 
    issue=$(echo "$base" | sed -e 's/^.*\([0-9]\{4\}\)$/\1/') 
    echo "$name" "$volume" "$issue" 
done 

输出的例子书:

to kill a mockingbird 1960 0001 

使用GNU sed的 '扩展正则表达式'模式(-r):

for file in $(find /home/user/books -type f -name '*.txt') 
do 
    base=$(basename $file .txt) 
    name=$( echo "$base" | sed -r -e 's/^(.*).V.*$/\1/' -e 's/\./ /g') # replace dots 
    volume=$(echo "$base" | sed -r -e 's/^.*V([0-9]{4}).*$/\1/') 
    issue=$(echo "$base" | sed -r -e 's/^.*([0-9]{4})$/\1/') 
    echo "$name" "$volume" "$issue" 
done 

使用\d符号(不正确的输出):

for file in $(find /home/user/books -type f -name '*.txt') 
do 
    base=$(basename $file .txt) 
    name=$( echo "$base" | sed -r -e 's/^(.*).V.*$/\1/' -e 's/\./ /g') # replace dots 
    volume=$(echo "$base" | sed -r -e 's/^.*V(\d{4}).*$/\1/') 
    issue=$(echo "$base" | sed -r -e 's/^.*(\d{4})$/\1/') 
    echo "$name" "$volume" "$issue" 
done 

输出:

to kill a mockingbird to.kill.a.mockingbird.V1960.0001 to.kill.a.mockingbird.V1960.0001 
+0

这也适用 - 谢谢你的帮助!也会为此投票,但我没有足够的声望! – 2013-03-11 07:23:06

3

无需使用SED,庆典可以用PARAM扩展处理。

假设所有的文本文件使用提到格式:

#!/bin/bash 
for file in $(find /home/user/books -type f -name '*.txt'); do 
    pre=${file%%.txt} 
    pre=${pre//./ } 
    name=${pre%% V*} 
    volume=${pre##* V} 
    volume=${volume%% *} 
    issue=${pre##* } 
    echo "Name: '$name' Volume: '$volume' Issue: '$issue'" 
done 
+0

这工作,谢谢! - 我想投票,但它不会让我! – 2013-03-11 07:21:54

相关问题