在多个目录中查找批处理文件

Batch-process files with find in multiple directories

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

如果您使用 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 选项,这样一个不匹配任何文件的模式就会展开为空(所以循环不会 运行) .

如果您真的想使用 find(例如,您在过去使用 Bash 的古董版本并且 globstar 不可用 — 所以使用 Tom Fenech 的解决方案不是一个选项),您必须生成一个 shell 来进行替换。标准方式是:

find . -name '*.flac' -type f -exec sh -c 'ffmpeg -i "" -c:a mp3 -b:a 320k  "${1%.flac}.mp3"' dummy {} \;

sh -c 将 运行 它的第一个参数,后续参数设置为从 0 开始的位置参数 。这就是为什么我放了一个虚拟参数(我称之为 dummy,但其他任何东西都可以)。

请注意,在 find-name 中,参数 *.flac 需要被引用。出于某种原因,您编辑了 post 并将 -name 谓词替换为 -regex 谓词:它真的没用,无论如何您仍然需要引用参数。