2011-08-16 64 views
2

我有文件,如列表:殼牌腳本(正則表達式來移動文件)

i60.st082313ea.jpg
i61.st51249c5e.jpg
i62.stef1fe5f2.jpg

我想通過將起始整數(例如60,61,62)遞減1來重命名目錄中的每個文件。

我做svn的 - 重命名使用類似以下的外殼:

for file in *.xml; 
    do svn mv $file `basename $file xml`json; 
done; 

但是,當涉及到創建一個正則表達式,並從文件的部分減去1,我在虧損。值得一提的是,該文件可能會在名稱的其他地方重複表達i[0-9]+,因此它只需匹配前導字符串。

任何幫助/教程/鏈接真的很感激。

+2

哪個殼? –

+0

woops。在Ubuntu 11.04工作。 – onassar

+0

這不是一個外殼。 –

回答

2
for file in *.jpg; do 
    newfilename=`echo $file | awk -F '.' '{ OFS=".";print "i" substr($1,2,2)+1, $2, $3}'` 
    mv $file $newfilename 
done; 

注:這僅適用,如果文件名匹配的實例中(如整數是在第二和第三的位置,並將該文件具有剛好兩個. S)。

HTH

+0

有無論如何,你可以包括擴展名爲.jpg,.jpeg或.png的可能性嗎? – onassar

+0

完美無缺地工作。謝謝! – onassar

+1

如果您的文件名有2個連續的空格,則可能無法使用。爲了解決這個問題,可以用'echo'$ file「'改變'echo $ file',或者更好的改成'printf'%s \ n」,「$ file」'。 – jfg956

1

偉大的是,您的輸入是非常規律的。因此,使用像

^i([0-9]+)(\..*)$ 

一個正則表達式將在輸入的起點開始,符合「我」作爲一個必要的字符,然後匹配一個十進制數,然後匹配輸入的休息,直到結束。

圓括號使組可用於捕獲匹配。如果您與bash匹配,捕獲組可在BASH_REMATCH(一個數組)中使用。有了這個正則表達式,你有兩個捕獲組:你想減少的數字,以及文件名的其餘部分。

要創建新文件名,您要連接字符'i',${BASH_REMATCH[1]} - 1${BASH_REMATCH[2]}

如果您與bash不匹配,請嘗試使用perl? (另外,你可以使用\d作爲我的特別喜愛的數字)。它在處理器上比sedawk重一點,但對於你想要做的事更容易。

sed支持反向引用,但要對它們進行算術運算,您必須從sed表達式(可執行)中調用shell命令。 awk並不真正支持反向引用,但gawk有一個幫助功能,gensub

1

,而無需創建爲每個文件重命名的過程,並在bash shell中(你可以瞭解哪些外殼使用的是通過鍵入命令echo $SHELL),假設你的文件名總是'i'開頭,後跟一個數字,然後由'.'

ls $.jpg | while read file; do 
    post_dot=${file#*.} 
    pre_dot=${file%%.*} 
    number=${pre_dot#i} 
    echo "mv "$file" "i$((number-1)).$post_dot"" 
done 

當你很高興與打印結果,在mv行的末尾刪除'echo "'開頭和'"'。在mv命令中的大約$filei$((number-1)).$post_dot對於說明文件名中的空格很重要。

0

我寫了一個小腳本我打電話mv_re雖然也許mv_evalmv_perl會更有意義:

#!/usr/bin/perl 

foreach (@ARGV) { 
    push(@evals,$_); 
} 

sub mv_eval { 
    my ($dirname) = @_; 
    opendir (my($dh), $dirname) or 
     die "Couldn't open dir '$dirname': $!"; 
    my @fs = readdir $dh; 
    foreach $f (@fs) { 
     $_ = $f; 
     foreach $e (@evals) { eval $e; } 
     print "mv '$f' '$_'\n" if ($_ ne $f); 
    } 
    closedir $dh; 
} 

mv_eval("."); 

它把每個參數的行Perl代碼,並在當前直接運行他們對每一個文件名。任何更改的文件名都會打印出適當的mv命令。因此mv_re s/www.//寫入腳本以從當前目錄中的每個文件中刪除第一個www.

理想情況下,我應該爲目錄或filespec添加可選的命令行參數,替代命令爲mv,以及一個選項,而不是爲用戶編寫腳本。