Debian

嘗試在 Perl 重命名工具(Debian)中進行算術運算

  • July 24, 2015

假設我有五個 mp3 文件:

01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
05-trackxyz.mp3

現在我快速收聽一下文件(控制台上的 mplayer 就可以解決問題),我發現曲目順序錯誤。05 實際上是 02,其餘的必須重命名。所以首先我會做一個臨時重命名:

01-trackfoo.mp3

02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
00-trackxyz.mp3

現在我們需要一個“轉變”:02 應該變成 03,03 應該變成 04,04 應該變成 05。為了盡量減少混淆,ex-05(現在是 00)稍後會被mv編輯。

我的方法是這樣的:(perl rename,由 Larry Wall 編寫,Debian 上的預設設置)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/' *

以及(稍後,在更多的 RTFM 之後)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/e' *

它們都不起作用,特別是因為修飾符除了/e[val]評估之外不接受任何其他內容,並且一旦您嘗試將評估與字元串結合起來就會拋出錯誤。可以做得很好,例如 將被評估為.bash``foo$((1+6))``foo7

那麼我該怎麼做(單行首選,不打算為此編寫一個完整的獨立腳本)?

你幾乎擁有它。/e您只需要使用引號和點運算符在 -modified 替換中顯式地製作文字字元串和字元串連接。

rename 's/0([2-4])([\s\S]+)/"0".($1+1).$2/e' *

單行首選,不打算為此編寫一個完整的獨立腳本

當事情變得如此復雜時,我看不出有什麼理由不寫劇本。您永遠不會記得如何從一次執行到下一次執行此操作,因此您最終要麼每次都重新發明它,要麼無論如何都將其包裝在腳本中。

對於這樣一件小事,我一般會開始嘗試在 Bash 中解決它:

#!/bin/bash
if [ -z "$1" ] ; then echo Need arguments. ; exit 1 ; fi

typeset -i i=1
for f in "$*"
do
   tailbits=`echo "$f" | sed -e 's/^[0-9]+//'`
   mv "$f" sertmp-`printf %02d $i`"$tailbits"
   i=i+1
done

for f in "sertmp-*"
do
   mv "$f" `echo "$f" | sed -e s/^sertmp-//` 
done

基本上,此腳本會去掉所有前導數字,然後在前面放置一個零填充的遞增序列號,文件根據您傳遞給腳本的順序編號。

它分兩個階段執行此操作,sertmp-第一次通過前綴以避免名稱衝突的任何風險。如果您呼叫此腳本mp3-renamer並將其稱為:

$ mp3-renamer 01-foo.mp3 03-bar.mp3 04-qux.mp3

如果您不使用 2 次通過來進行重命名,那麼您在第一次重命名時會遇到微不足道的衝突。( 01-foo.mp3-> 01-foo.mp3.)

但是,如果您這樣稱呼它:

$ mp3-renamer 02-foo.mp3 01-foo.mp3

您在第一次重命名時意外刪除01-foo.mp3了 1-pass 重命名。

如果問題變得更複雜,我會用 Perl 重寫它。那時,您可以使用散列來保存舊->新名稱映射,並使用一些聰明的程式碼來計算出正確的重命名順序,以避免需要 2 遍。

引用自:https://unix.stackexchange.com/questions/47006