如何基于ID3标签批量修改所有子目录中MP3文件的文件名
如何基于ID3标签批量修改所有子目录中MP3文件的文件名
你提到需要批量修改包括子目录在内的所有MP3文件名,用它们ID3标签里的曲目号和标题来命名对吧?之前你试过单个文件夹用kid3-cli或eyeD3,这里给你调整优化命令,让它们能遍历所有子目录,同时也补充一个可选的工具方案。
方法一:用kid3-cli遍历所有子目录
kid3-cli本身支持标签读取,但要覆盖所有子目录,结合find命令就能实现批量处理:
find . -type f -name "*.mp3" -exec kid3-cli -c 'fromtag "%{track}-%{title}" 1' {} \;
简单解释下:find .从当前目录开始递归查找,-type f确保只处理文件(排除目录),-name "*.mp3"筛选出MP3文件;-exec会把每个找到的文件传给kid3-cli,%{track}-%{title}就是用曲目号加标题作为新文件名,最后的1表示如果有同名文件直接覆盖,不需要覆盖的话可以去掉这个参数。
方法二:用eyeD3处理所有子目录
你之前的eyeD3命令有点小问题,-execdir会在每个文件所在目录重复执行*.mp3,容易造成重复处理,改成下面的命令更准确:
find . -type f -name "*.mp3" -exec eyeD3 --rename '$track:num-$title' {} \;
这里$track:num会提取纯数字格式的曲目号,$title对应标签里的标题,-exec直接对每个找到的MP3文件单独执行重命名,就不会出现重复处理的情况了。
其他可选工具:ffmpeg
如果你已经装了ffmpeg,也能用它来完成这个操作——虽然它主打音视频处理,但读取ID3标签并重命名也很顺手:
find . -type f -name "*.mp3" -exec bash -c ' # 提取曲目号,去掉总曲目数(比如把"01/10"变成"01") track=$(ffprobe -v error -show_entries format_tags=track -of default=noprint_wrappers=1:nokey=1 "$1" | cut -d/ -f1) # 提取标题,过滤掉文件名不允许的特殊字符 title=$(ffprobe -v error -show_entries format_tags=title -of default=noprint_wrappers=1:nokey=1 "$1" | sed "s/[\/:*?"<>|]//g") # 重命名,-n参数避免覆盖已存在的文件 mv -n "$1" "$(dirname "$1")/${track}-${title}.mp3" ' _ {} \;
备注:内容来源于stack exchange,提问作者Gene Tyle




