我有一个包含多个子目录的目录,其中包含.flac
个文件。我想将它们批量转换为.mp3
。路径名称包含空格。现在我想做这样的事情
find . -type f -regex .*.flac -exec ffmpeg -i {} -c:a mp3 -b:a 320k \;
但问题是,如何使用{}
并将flac
替换为mp3
来为ffmpeg提供输出文件名?在bash中,可以使用变量替换${file%.flac}.mp3
,但我不能在此处应用它。基于sed
的方法似乎与find
无关。
对此有什么简单的解决方案吗?
答案 0 :(得分:3)
如果你正在使用bash,我会使用globstar
,这会扩展到所有.flac
个文件的列表:
shopt -s globstar nullglob
for file in **/*.flac; do
[[ -f $file ]] || continue
out_file=${file%.flac}.mp3
ffmpeg # your options here, using "$out_file"
done
支票[[ -f $file ]]
会跳过以.flac
结尾的所有目录。如果你没有这些,你可以跳过这个。
我还启用了nullglob
shell选项,因此不匹配任何文件的模式扩展为空(因此循环不会运行)。
答案 1 :(得分:2)
如果你真的想使用find
(例如,你曾经使用古董版Bash并且globstar
无法使用 - 那么使用Tom Fenech的解决方案不是一种选择),你必须生成一个shell来进行替换。标准方式是:
find . -name '*.flac' -type f -exec sh -c 'ffmpeg -i "$1" -c:a mp3 -b:a 320k "${1%.flac}.mp3"' dummy {} \;
sh -c
将运行其第一个参数,子序列参数将设置为从0
开始的位置参数。这就是为什么我放置一个虚拟参数(我称之为dummy
,但其他任何东西都可以)。
请注意,在find
的{{1}}中,需要引用参数-name
。出于某种原因,您编辑了帖子并用*.flac
谓词替换了-name
谓词:它真的没用,而且仍然需要引用该参数。