You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 16.04遍历子文件夹批量转码MP4脚本报错解决方案咨询

解决Ubuntu 16.04下多层文件夹批量转码MP4的脚本错误问题

我帮你分析下这个问题哈,你碰到的ENOENT: no such file or directory, stat '*.mp4'错误主要有两个原因,咱们一步一步来解决:

首先是脚本的语法问题

你写的脚本里,cd "$D"后面没有加分号或者换行,导致它和后面的for i in *.mp4连在一起,shell解析的时候会出错,这是第一个要修正的点。

其次是空目录的处理问题

当某个子目录里没有.mp4文件时,for i in *.mp4不会自动跳过,而是会把*.mp4当作一个实际的文件名去查找,自然就会报“找不到文件”的错误。

修正后的基础脚本

咱们先把语法和空目录问题解决,修改后的脚本如下:

shopt -s nullglob  # 开启nullglob,当通配符匹配不到文件时会返回空,而不是保留原字符串
for D in ./*; do
    if [ -d "$D" ]; then
        cd "$D" || continue  # 如果cd失败(比如权限问题),直接跳过当前目录
        for i in *.mp4; do
            # 注意:这里先改成带后缀的文件名测试,避免直接覆盖原文件
            ffmpeg -i "$i" -codec copy -acodec copy -shortest -map 0:v -map 0:m:language:eng "${i%.*}_fixed.mp4"
        done
        cd ..
    fi
done
shopt -u nullglob  # 关闭nullglob,避免影响后续操作

解释下关键改动:

  • 加入shopt -s nullglob:开启后,当*.mp4匹配不到文件时,循环不会执行,自然就不会报错
  • 在cd "$D"后面加了|| continue:如果切换目录失败(比如权限不足),直接跳过这个目录,避免后续操作出错
  • 把输出文件名改成了${i%.*}_fixed.mp4:防止直接覆盖原文件,测试没问题后你再改成原文件名

更高效的替代方案:用find命令递归处理

其实不用手动写嵌套循环,find命令可以直接递归遍历所有子目录里的.mp4文件,更简洁可靠,命令如下:

find . -type f -name "*.mp4" -exec sh -c '
    for file do
        # 同样,先改成带后缀的文件名测试
        output="${file%.*}_fixed.mp4"
        ffmpeg -i "$file" -codec copy -acodec copy -shortest -map 0:v -map 0:m:language:eng "$output"
        # 如果测试没问题,想要覆盖原文件,可以把上面的output改成$file,然后加-y参数强制覆盖:
        # ffmpeg -y -i "$file" -codec copy -acodec copy -shortest -map 0:v -map 0:m:language:eng "$file"
    done
' sh {} +

这个命令的优势:

  • 自动递归所有子目录,不管层级有多深
  • 只会处理实际存在的.mp4文件,不会出现空匹配的问题
  • 用-exec ... {} +可以批量传递文件,比逐个处理更高效

最后别忘了测试的时候先不要覆盖原文件,确认转码后的文件没问题再替换哦!

内容的提问来源于stack exchange,提问作者Adrixa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:32:58