Bash按文件类型批量修改目录及子目录视频元数据标题问题求助
原脚本问题分析
- 遍历范围不足:
for file in *仅匹配当前目录第一层内容,无法递归检索子目录下的文件 - 分支逻辑错误:mp4处理分支硬编码了
*.mp4参数,每次触发分支都会重复扫描全量mp4文件,逻辑冗余且效率极低 - 缺少类型校验:没有区分遍历对象是文件还是目录,目录会命中else分支输出错误提示,也会导致后缀匹配失效
修正方案
方案1:使用globstar递归匹配(适配bash 4.0+版本,写法简洁)
bash 4.0及以上版本支持globstar特性,可以直接用**匹配任意层级子目录:
#!/bin/bash # 开启递归通配符,未匹配到文件时不返回通配符本身 shopt -s globstar nullglob # 递归遍历所有mkv、mp4文件 for file in **/*.{mkv,mp4}; do # 跳过目录,仅处理文件 [[ -f "$file" ]] || continue # 取不带路径的文件名作为标题,如需保留全路径直接使用$file即可 title=$(basename "$file") if [[ $file == *.mkv ]]; then mkvpropedit "$file" --set "title=$title" elif [[ $file == *.mp4 ]]; then exiftool "-Title<$title" "$file" -overwrite_original fi done
如果不需要额外自定义逻辑,也可以更简化:
shopt -s globstar nullglob # 批量处理所有mkv文件 for f in **/*.mkv; do mkvpropedit "$f" --set "title=$(basename "$f")"; done # exiftool本身支持递归,直接一行处理所有mp4 exiftool "-Title<Filename" -ext mp4 -r . -overwrite_original
方案2:使用find命令(兼容性更强,适配所有bash版本)
适合老版本bash环境,同时天然支持处理含特殊字符的文件名:
#!/bin/bash # 递归查找所有mkv、mp4文件,-print0配合read处理特殊文件名 find . -type f \( -iname "*.mkv" -o -iname "*.mp4" \) -print0 | while IFS= read -r -d '' file; do title=$(basename "$file") if [[ $file == *.mkv ]]; then mkvpropedit "$file" --set "title=$title" elif [[ $file == *.mp4 ]]; then exiftool "-Title<$title" "$file" -overwrite_original fi done
额外说明
- 如需去掉文件后缀作为标题,可修改title变量取值为
title=$(basename "$file" .${file##*.}) - 正式运行前可以把执行命令替换为
echo输出,确认匹配的文件和标题规则符合预期后再实际执行
内容的提问来源于stack exchange,提问作者Hisfantor
相关产品推荐
相关产品推荐

