在具有特定扩展名的所有文件夹和子文件夹中运行命令

时间:2019-06-29 05:05:17

标签: bash shell ffmpeg

当前,我正在尝试在Linux服务器(Ubuntu 16.04)上运行命令以重新编码所有.mp4文件。但是我在文件夹和子文件夹中有很多文件,我将浪费大量时间手动运行这些命令

这是我的剧本:

for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D"
        for i in *.mp4; do
            ffmpeg -i "$i" -codec copy -acodec copy -shortest -map 0:v -map 0:m:language:eng "${i%.*}.mp4"
        done
        cd ..
    fi
done

但是,我收到此错误:

Error: ENOENT: no such file or directory, stat '*.mp4'

我该如何解决?

谢谢。

2 个答案:

答案 0 :(得分:4)

为此使用find。它为您处理子目录递归。像这样:

find . -type f -name "*.mp4" -exec ffmpeg -i {} -codec copy -acodec copy -shortest -map 0:v -map 0:m:language:eng {}  \; -print
  • find将自动处理当前目录和所有子目录
  • -type f:仅搜索文件
  • `-name“ * .mp4”:仅具有mp4扩展名的文件
  • -exec COMMAND {} \;:在找到的所有文件上执行该命令。 {}将替换为每个文件的文件名。 \;结束命令。
  • -print:将打印已处理的文件

就您的代码而言,目录可能没有任何“ * .mp4”文件,因此在您打入此类目录时出现no such file or directory, stat '*.mp4'错误。

答案 1 :(得分:0)

示例(无效,仅执行echo ...):

$ find \
  . \
  -type f \
  -name '*.mp4' \
  -exec sh -c '
    for src in "$@"; do
      dst="${src%.*}.mkv"
      echo ffmpeg ... "$src" ... "$dst"
    done
  ' sh {} + \
  -print \
;

您必须用命令行替换echo ffmpeg ... "$src" ... "$dst"才能用于生产。您可以从示例中删除-print