![如果文件名包含括号则查找失败](https://linux22.com/image/150638/%E5%A6%82%E6%9E%9C%E6%96%87%E4%BB%B6%E5%90%8D%E5%8C%85%E5%90%AB%E6%8B%AC%E5%8F%B7%E5%88%99%E6%9F%A5%E6%89%BE%E5%A4%B1%E8%B4%A5.png)
我正在尝试在循环内使用 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
答案1
问题是[
和]
是全局字符。例如,考虑这个文件:
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*'
最简单的方法是使用printf
和%q
。所以改变这一行:
filename="$(basename "$file" .mkv)"
对此:
filename=$(printf '%q' "$(basename "$file" .mkv)")
或者,没有周围的命令替换printf
:
printf -v filename '%q' "$(basename "$file" .mkv)"