2013-03-10 43 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

相關問題