我的文件夹中有三个.wav
文件,我想用ffmpeg将它们转换为.mp3
。
我写了这个 bash 脚本,但是当我执行它时,只有第一个被转换为 mp3。
我应该怎么做才能让脚本继续浏览我的文件?
这是脚本:
#!/bin/bash
find . -name '*.wav' | while read f; do
ffmpeg -i "$f" -ab 320k -ac 2 "${f%.*}.mp3"
done
使用 -nostdin
标志禁用交互模式,
ffmpeg -nostdin -i "$f" -ab 320k -ac 2 "${f%.*}.mp3"
或者ffmpeg
从控制终端而不是标准输入读取其输入。
ffmpeg -i "$f" -ab 320k -ac 2 "${f%.*}.mp3" </dev/tty
请参阅 ffmpeg 文档中的 -stdin
/-nostdin
标志
如果您确实需要find
(用于查找子目录或执行更高级的过滤),请尝试以下操作:
find ./ -name "*.wav" -exec sh -c 'ffmpeg -i "$1" -ab 320k -ac 2 "$(basename "$1" wav).mp3"' _ {} ;
将find
的输出管道连接到while
回路有两个缺点:
- 在匹配的文件名包含换行符的(可能很少见)情况下,它会失败。
-
ffmpeg
,出于某种我不知道的原因,将从标准输入中读取,这会干扰read
命令。这很容易解决,只需从/dev/null
重定向标准输入,即find ... | while read f; do ffmpeg ... < /dev/null; done
.
在任何情况下,都不要将命令存储在变量名中并使用 eval
来评估它们。这是危险的,也是一个坏习惯。如果您确实需要分解实际的命令行,请使用 shell 函数。
没有理由查找,只需使用 bash 通配符通配符
#!/bin/bash
for name in *.wav; do
ffmpeg -i "$name" -ab 320k -ac 2 "${name%.*}.mp3"
done