鉴于需要从子目录中的视频文件中提取音频,如何正确命名生成的文件?
下面的单行代码有效,但保留了旧的文件扩展名。
find -name "*.mp4" -exec ffmpeg -i {} -vn -acodec copy {}.aac -hide_banner \;
当前结果:
foobar.mp4 --> foobar.mp4.aac
期望的结果:
foobar.mp4 --> foobar.aac
鉴于需要从子目录中的视频文件中提取音频,如何正确命名生成的文件?
下面的单行代码有效,但保留了旧的文件扩展名。
find -name "*.mp4" -exec ffmpeg -i {} -vn -acodec copy {}.aac -hide_banner \;
当前结果:
foobar.mp4 --> foobar.mp4.aac
期望的结果:
foobar.mp4 --> foobar.aac
本身没有任何机制
find
允许您从替换的任何内容中获取子字符串{}
。甚至{}.aac
可能不支持添加后缀(就像您所做的那样:)。POSIX 说:对于许多实现,诸如此类的事情
foo{}bar
确实有效,但仍需注意。要做更多的事情,您肯定需要一个可以操纵字符串的工具;通常是一个外壳。在你的情况下:这里
${1%.*}
负责获取不带扩展名的路径名。您可能想在传递
ffmpeg -i "$1"
给. 不要这样做。我的另一个答案解释了为什么后者是错误的(以及为什么比 更好)。ffmpeg -i "{}"
sh
find . -name …
find -name …
另一种方法是:
编辑: 我不知道为什么我会想到这样一个循环,当更简单的循环就足够了:
但是,如果确实需要递归
find
,根据 Scott 的评论,我决定改进最后一个答案。我通过进程替换使用 while 循环和来自 find 的输入:请注意,ffmpeg 需要
-nostdin
一个 while 循环。exec 和 xargs 通常可能比 while 循环更有效,但由于此实例将由 ffmpeg 进行处理,因此我认为不会对性能造成重大影响。