通过交换文本重命名文件:寻求更简洁的实现方案
用
rename工具简化批量文件重命名(交换文本内容) 当然可以!手写bash循环处理这类批量重命名确实容易写得繁琐,而rename工具(尤其是Perl版本的)刚好擅长这类基于模式匹配的文本交换操作,能大幅简化代码,一行命令就能搞定大部分场景。
先模拟你可能用到的bash实现(常见繁琐写法)
假设你的原文件名格式是[前缀]_[后缀].txt,要交换前缀和后缀变成[后缀]_[前缀].txt,bash脚本大概是这样:
for file in *.txt; do # 用awk分割下划线,交换前后部分 new_name=$(echo "$file" | awk -F '_' '{print $2"_"$1}') mv "$file" "$new_name" done
这种写法需要循环遍历、调用外部工具处理字符串,步骤多且容易出错。
用Perl版rename实现(推荐)
大多数Linux发行版默认的rename是Perl版本的(如果不是,可以通过包管理器安装perl-rename),它支持Perl正则表达式,处理文本交换非常顺手。
还是以上面的文件名格式为例,一行命令就能完成:
rename 's/^([^_]+)_([^_]+)\.txt$/$2_$1.txt/' *.txt
正则逻辑解释:
^([^_]+)_([^_]+)\.txt$:精准匹配前缀_后缀.txt格式的文件名,用括号分别捕获前缀(对应变量$1)和后缀(对应变量$2)$2_$1.txt:直接交换两个捕获组的位置,生成目标格式的文件名
如果你的文件名格式更复杂(比如包含多个下划线、特殊字符),只需要调整正则的捕获规则就行——Perl正则的灵活性完全能覆盖绝大多数文本交换场景。
小技巧:先验证再执行
怕写错规则搞砸文件名?可以先加-n参数做模拟运行(dry run),只会输出要修改的文件名,不会实际操作:
rename -n 's/^([^_]+)_([^_]+)\.txt$/$2_$1.txt/' *.txt
确认输出的重命名逻辑正确后,再去掉-n执行实际修改。
如果需要递归处理子目录里的文件,还可以结合find命令:
find . -type f -name "*.txt" -exec rename 's/^([^_]+)_([^_]+)\.txt$/$2_$1.txt/' {} +
内容的提问来源于stack exchange,提问作者Louis D
相关产品推荐
相关产品推荐

