Bash

如果文件名包含括號,則查找失敗

  • March 25, 2019

我正在嘗試在循環中使用 find 來創建一個包含與文件名 + 所需字元串匹配的文件的變數

例子:

file1.en.srt
file1.mkv
file1.pt.srt

這是程式碼的相關部分:

shopt -s nullglob
shopt -s nocaseglob

if [ -d "$1" ]; then
   for file in "${1%/}/"*mkv; do
       # Get filename to match against subs and audios
       filename="$(basename "$file" .mkv)"

       # Find matching subtitle file
       engsubs="$(find . -name "$filename*en.srt*" | sed -e 's,^\./,,')"   

       # Find matching audio file
       engaudio="$(find . -iname "$filename*en.ac3" -o -iname "$filename*en.eac3" -o -iname "$filename*en.dts" | sed -e 's,^\./,,')" 
   done
fi

如果文件不包含括號,它可以工作,但是find命令找不到名稱包含括號的文件的任何內容。為什麼會這樣?我想創建一個像$en這樣包含的變數file1.en.srt

問題是[並且]是全域字元。例如,考慮這個文件:

ba[r].mkv

在該文件上執行腳本時,$filename將為:ba[r]因此您的find命令將是:

find . -name 'ba[r]*pt-BR.srt*'

由於[r]是單字母字元類,因此意味著r. 所以你的命令正在尋找一個以 開頭的文件名ba,然後是一個r,然後是任何字元,然後是pt-BR.srt任何字元。您需要轉義括號:

find . -name 'ba\[r\]*pt-BR.srt*'

最簡單的方法是使用printfand %q。所以只要改變這一行:

filename="$(basename "$file" .mkv)"

對此:

filename=$(printf '%q' "$(basename "$file" .mkv)")

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