在多个目录中使用find批处理文件

时间:2016-06-19 10:55:13

标签: bash unix find batch-processing gnu-findutils

我有一个包含多个子目录的目录,其中包含.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无关。 对此有什么简单的解决方案吗?

2 个答案:

答案 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谓词:它真的没用,而且仍然需要引用该参数。