Bash

將電視節目的文件名重命名和清理為 S01E01.mp4 等

  • September 17, 2021

如果我有一些名字很糟糕的電視節目,我需要清理它們

$ ls
Some_Series.1_Episode.1.mp4  'Some Series01.Episode02.mp4' SomeSeries1Episode03.mp4

我需要批量重命名它們成為

$ ls
S01E01.mp4  S01E02.mp4  S01E03.mp4

我使用了以下腳本並且它有效,但僅當原始文件名包含系列和劇集編號 01 02 03 而不是 1 2 3

#!/bin/bash
# rename tv show filenames to be kodi friendly
cd /mnt/2tb_hd/con/
if [ $? == 1 ]; then 
   exit
fi
for filename in *; do
       if [[ "$filename" =~(\**).*(.*[0-9][0-9]).*([0-9][0-9]).*(\....)$ ]]; then
           result=$(echo mv \"$filename\" S${BASH_REMATCH[2]}E${BASH_REMATCH[3]}${BASH_REMATCH[4]}\") 

               if [[ $? == 0 ]] ; then 
                   mv "$filename" "S${BASH_REMATCH[2]}E${BASH_REMATCH[3]}${BASH_REMATCH[4]}"
               fi
           fi
       done
       exit

我需要使此程式碼在執行第二個重命名循環之前更改文件名中的任何 1 2 3 4 5 等以具有 0 填充,或者只是更改我已經必須更改 01 或 1 的程式碼,而不管 0 填充如何。

抱歉,如果這看起來真的很明顯,但我是 bash 新手,所以請原諒我。


我已經更新了腳本,現在我遇到了第 8 集和第 9 集的問題。我收到以下錯誤

line 10: printf: 08: invalid octal number

所以第 8 集和第 9 集失去了,但是每個超過 7 集的系列都有一個額外的文件 S02E00.mkv。

改編的劇本

#!/bin/bash
# rename tv show files to kodi friendly format S01E01 etc
cd /mnt/2tb_hd/Adults/TV_Shows/Breaking\ Bad/
if [ $? == 1 ]; then 
   exit
fi
reg='^([^0-9]*)([0-9][0-9]*)[^0-9]*([0-9][0-9]*).*(\....)$'
for filename in *.*; do
     if [[ $filename =~ $reg ]]; then
             printf -v newname 'S%02dE%02d%s' "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}" "${BASH_REMATCH[4]}"
                 mv "$filename" "$newname"
               fi
           done
       exit

有關測試執行的完整結果,請參見http://pastebin.com/2XRH85ua

使用printf, 格式字元串指定欄位寬度和整數的零填充,例如

printf -v newname 'S%02dE%02d%s' "$((10#${BASH_REMATCH[2]}))" "$((10#${BASH_REMATCH[3]}))" "${BASH_REMATCH[4]}"

請注意$((10#${BASH_REMATCH[n]}))在以下情況下使用強制十進制評估09

測試(順便說一句,我稍微修改了你的正則表達式):

reg='^([^0-9]*)([0-9][0-9]*)[^0-9]*([0-9][0-9]*)(\....)$'
for filename in *.mp4; do
 if [[ $filename =~ $reg ]]; then
   printf -v newname 'S%02dE%02d%s' "$((10#${BASH_REMATCH[2]}))" "$((10#${BASH_REMATCH[3]}))" "${BASH_REMATCH[4]}"
   echo mv "$filename" "$newname"
 fi
done
mv Some Series01.Episode02.mp4 S01E02.mp4
mv SomeSeries1Episode03.mp4 S01E03.mp4
mv Some_Series.1_Episode.1.mp4 S01E01.mp4

可能更健壯的方法是使用正則表達式來匹配前兩個數字序列,並使用 shell 參數替換來處理擴展:

reg='([0-9][0-9]*)[^0-9]*([0-9][0-9]*)'
for filename in *.mp4 *.mkv; do
 name="${filename%.*}"
 ext="${filename##*.}"
 if [[ $name =~ $reg ]]; then
   printf -v newname 'S%02dE%02d.%s' "$((10#${BASH_REMATCH[1]}))" "$((10#${BASH_REMATCH[2]}))" "${ext}"
   echo mv "$filename" "$newname"
 fi
done
mv Some Series01.Episode02.mp4 S01E02.mp4
mv SomeSeries09Episode10.mp4 S09E10.mp4
mv SomeSeries1Episode03.mp4 S01E03.mp4
mv Some_Series.1_Episode.1.mp4 S01E01.mp4
mv Breaking.Bad.S01E01.576p.BluRay.DD5.1.x264-HiSD.mkv S01E01.mkv

或者,如果你的系統有基於 perl 的rename/prename命令,你可以這樣

prename -vn -- 's/.*(\d+).*(\d+)/sprintf "S%02dE%02d.mp4", $1, $2/e' *.mp4

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