Bash

用於定位和刪除文件名中的子字元串的 Bash shell 腳本

  • August 22, 2011

我正在嘗試在 Mac OS X 10.6(由 Automator Action 呼叫)中編寫一個 bash shell 腳本,以重命名我多年來命名錯誤的電視節目 DVD 撕裂。我想刪除文件名中的部分文本。我想刪除在我知道將始終出現在文件名中的特定字元系列之後出現的文本。但我不知道在已知的一系列字元之前或之後會出現多少個字元。我也不知道之前或之後的文本是否會包含多個句點或破折號。一個例子可能會有所幫助:

大爆炸理論.S01E01.xxxxxxxxxxx.mp4

我知道每個文件將始終包含 SxxExx 格式的字元串,其中 x 始終是數字。但我不知道數字會是多少。我想讓文件名達到並包括 SxxExx 字元串和文件副檔名,但去掉其他所有內容。所以對於上面的例子,我最終會得到:

大爆炸理論.S01E01.mp4

我嘗試過使用 bash 的內置字元串替換命令。我認為 expr index 命令會給我 SxxExx 字元串的起點,然後我可以使用 ${filename:offset:length} 僅提取文件名的所需部分(我已經知道副檔名,因此可以重新添加)。但似乎 OS X 版本的 expr 不包括索引功能。我以前只用 Basic 和 LotusScript 編寫過腳本。在那些環境中,使用諸如“Like”和“Instr”或“Mid”之類的命令會相當容易。但是在bash中我就是想不通。我花了幾個小時在Google上搜尋,試圖了解如何使用正則表達式來定位文件名中的“SxxExx”子字元串,但我就是想不通。我希望一些聰明的 UNIX 腳本編寫者能夠幫助我!

嘗試這個:

newname=`echo "$filename" | sed -e 's/\(S[0-9][0-9]E[0-9][0-9]\).*\.mp4/\1.mp4/'`

正則表達式是:

  • 開始一個小組 ( ( )
  • 匹配 SXXXXX,其中 X 是 0 到 9 之間的數字
  • 結束組 () )
  • 匹配任意數量的任意字元(換行符除外)
  • 匹配顯式字元串 ( .mp4 )

在替換錶達式中:

  • 替換為第一組中匹配的字元串( \1 )
  • 替換為顯式字元串 ( .mp4 )

假設您有文件中包含路徑的file-list文件名列表,請嘗試以下操作

while IFS= read -r path; do
 newpath=$(printf '%s\n' "$path" |
   sed 's/\(.*S[0-9]*E[0-9]*\.\).*\.\([^.]*\)$/\1\2/')
 echo mv -- "$path" "$newpath"
done <file-list

使用的正則表達式的含義sed,也與範例輸入進行比較"The.Big.Bang.Theory.S01E01.xxxxxxxxxxx.mp4"

\(                               start of group 1
.*        The.Big.Bang.Theory.   any sequence of characters
S[0-9]*   S01                    a capital S followed by 0 or more digits
E[0-9]*   E01                    a capital E followed by 0 or more digits
\.        .                      a dot
\)                               end of group 1
.*        xxxxxxxxxxx            any sequence of characters
\.        .                      a dot
\(                               start of group 2
[^.]*     mp4                    a sequence of 0 or more non-dot characters
\)                               end of group 2
$                                end of line

在輸出中,字元串的\1\2意思是“輸出 group1 後跟 group2(所以要刪除xxxxxxxxxxx.

刪除echo如果滿意。

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