批量重命名子目录下MP3文件:移除首尾指定字符
解决递归批量重命名MP3文件的问题
我懂你现在的痛点——原来的命令只能处理当前目录下的文件,没法钻进子文件夹里批量修改那些MP3的名字。这里给你几个靠谱的解决方案,你可以根据自己的系统环境来选:
方案1:用find + Perl版rename(推荐,简洁高效)
如果你的系统装的是Perl版本的rename(大多数Linux发行版比如Ubuntu、Debian默认都是这个),可以直接用正则表达式批量处理:
find . -type f -name "*.mp3" -exec rename 's/^.{3}(.*).$/$1.mp3/' {} +
命令拆解:
find . -type f -name "*.mp3":递归遍历当前目录(.)下所有后缀为.mp3的文件-exec rename ... {} +:把找到的所有文件传给rename命令批量处理- 正则表达式
s/^.{3}(.*).$/$1.mp3/:^.{3}:匹配文件名开头的3个任意字符(.*):捕获中间的核心文件名(就是你想要保留的部分).:匹配文件名最后1个字符$1.mp3:把捕获到的核心部分加上.mp3作为新文件名
方案2:用find + Bash参数扩展(兼容性更强)
如果你的系统用的是util-linux版本的rename(比如CentOS、RHEL的某些版本),或者你更习惯用原生Bash语法,可以用这个方案:
find . -type f -name "*.mp3" -exec bash -c ' for file do # 提取文件所在目录和文件名 dir=$(dirname "$file") base=$(basename "$file") # 截取文件名:跳过前3个字符,去掉最后1个字符,再加.mp3后缀 new_base="${base:3:-1}.mp3" # 执行重命名(加-v可以看到操作过程,方便验证) mv -v "$file" "$dir/$new_base" done ' bash {} +
关键细节:
${base:3:-1}是Bash的参数扩展语法:3表示从第4个字符开始截取(索引从0开始),-1表示截取到倒数第2个字符(也就是去掉最后1个字符)- 建议先把
mv -v改成echo mv -v,先预览一下所有重命名操作,确认没问题再执行实际修改
为什么原来的命令不生效?
你之前写的for file in ??????*只会遍历当前目录下的文件,没有递归进入子目录的逻辑,所以没法处理那些1、2、3等子文件夹里的MP3。用find命令就能完美解决递归遍历的问题啦~
内容的提问来源于stack exchange,提问作者Gloytos htyqo




