如何转义文件名中的$和`以解决find -exec执行失败问题?
处理含特殊字符的MP3文件名时的ID3标签修改问题
问题场景
原本使用以下脚本批量修改MP3文件的ID3标签:
find -name "*.mp3" -exec bash -c 'eyeD3 --to-v1.1 "{}"' \;
但遇到包含美元符号($)、反引号(`)的文件名时执行失败,报错:
bash: -c: line 0: unexpected EOF while looking for matching ``' bash: -c: line 1: syntax error: unexpected end of file
失败的文件名示例:
08 - Sam Smith - I'm Not The Only One (Feat. A$AP Rocky).mp3 02 - The Vaccines - Wreckin` Bar (Ra Ra Ra).mp3
问题原因
find的{}会直接替换为文件名,当文件名包含$、`等shell特殊字符时,嵌套的bash -c会将这些字符解析为shell语法(比如反引号触发命令替换、美元符号触发变量展开),导致语法错误。
解决方案
方案1:直接用find -exec执行命令(推荐)
不需要通过bash中转,让find直接将文件名作为参数传给eyeD3,完全规避shell解析问题:
find -name "*.mp3" -exec eyeD3 --to-v1.1 {} \;
方案2:正确传递参数给bash -c
如果必须使用bash -c(比如需要添加复杂逻辑),将文件名作为位置参数传递,而非直接嵌入命令字符串:
find -name "*.mp3" -exec bash -c 'eyeD3 --to-v1.1 "$1"' _ {} \;
_是占位符,作为bash的$0(shell名称),不影响实际逻辑"$1"会完整保留文件名的特殊字符,避免被shell解析
方案3:批量处理提升效率
用+代替;,让find一次性传递多个文件名,减少bash进程启动次数:
find -name "*.mp3" -exec bash -c 'for file in "$@"; do eyeD3 --to-v1.1 "$file"; done' _ {} +
内容的提问来源于stack exchange,提问作者Megalithic
相关产品推荐
相关产品推荐

