针对特定扩展名和子文件夹递归循环

时间:2017-02-10 04:38:57

标签: bash recursion ffmpeg

我一直在尝试将flac转换为m4a,我有下面的脚本来完成这项工作,但它不是递归的:

for f in *.flac; do
    ffmpeg -i "$f"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"
done

对于递归,我确实尝试了几种方法,但没有一种方法,这就是我尝试过的方法 (文件名上的空格是这里的问题)

for f in `find . $PWD -iname *.flac`; do
    ffmpeg -i "$f"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"
done

和这个

find . -type f -iname "*.flac" -print0 |
    while IFS= read -r -d $'\0' line; do
        echo "$line"
        ffmpeg -i "$line"  -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${f%.flac}.m4a"; done   
    done

他们都没有工作。

2 个答案:

答案 0 :(得分:2)

第二次尝试因单词拆分而失败:find的输出被拆分。

您的上一次尝试可行,但有一个done太多,您在$f "${f%.flac}.m4a"使用${line%.flac}.m4a"shopt -s globstar

我改用了glob(需要for fname in **/*.flac; do ffmpeg -i "$fname" -vf "crop=((in_w/2)*2):((in_h/2)*2)" \ -c:a alac "${fname%.flac}.m4a" done ):

find

这将搜索当前目录的整个子树,而不需要left

1 Bash 4.0或更新版

答案 1 :(得分:2)

find选项与find . -name "*.flac" -execdir bash -c 'ffmpeg -i "$0" -vf \ "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${0%.flac}.m4a"' {} \; 一起使用:

.flac

.m4a递归匹配/重新编码-exec个文件,并将它们保存在同一目录中。使用-execdir代替-execdir任何重新编码的文件都将保存到上面执行命令的位置 - 这可能不是您想要的。

  

-exec主要内容与shopt主要内容相同                实例将从该目录执行的异常                保存当前文件。

此解决方案效果很好,特别是如果您的bash版本不包含globstar的{​​{1}}。

Another example of ffmpeg re-encoding using find and -execdir。 (更复杂)