2

我有一个包含多个子目录的目录,其中包含.flac文件。我想将它们批量转换为.mp3. 路径名包含空格。现在我想做这样的事情

find . -type f -regex .*.flac -exec ffmpeg -i {} -c:a mp3 -b:a 320k  \;

但问题是,我如何使用{}和替代flacmp3ffmpeg 一个输出文件名?在 bash 中,可以使用变量替换${file%.flac}.mp3,但我不能在这里应用它。sed基于 - 的方法似乎也不适用于find任何一种。有什么简单的解决方案吗?

4

2 回答 2

4

如果您使用的是 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. 如果你没有这些,你可能会跳过这个。

我还启用了nullglobshell 选项,以便与任何文件不匹配的模式扩展为空(因此循环不会运行)。

于 2016-06-19T11:02:33.313 回答
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's-name中,*.flac需要引用参数。出于某种原因,您编辑了您的帖子并将-name谓词替换为-regex谓词:它真的没用,而且您仍然需要引用参数。

于 2016-06-19T11:19:26.113 回答