如何调整rename脚本以支持任意数量下划线分隔组的文件名反转?
问题:让File::Rename脚本支持任意数量下划线分隔组的文件名反转重命名
现有一行File::Rename的rename(1)工具脚本,可将Foo_Bar_Baz.txt这类文件名重命名为Baz_Bar_Foo.txt,脚本内容如下:
rename -n 's/(\w+)_(\w+)_(\w+)/join "_", reverse @{^CAPTURE}/xe' ./*.txt
但该脚本硬编码了下划线分隔组的数量,仅能处理三组的情况,无法适配Foo_Bar或Aaa_Bbb_Ccc_Ddd这类不同组数的文件名,请问如何调整脚本使其支持任意数量的下划线分隔组?
解决方法
核心思路是放弃硬编码捕获组,改为先匹配所有下划线分隔的单词块,再通过字符串拆分、反转、拼接实现重命名。推荐使用以下脚本:
rename -n 's/^(\w+(?:_\w+)*)\.txt$/join "_", reverse split /_/, $1/e' ./*.txt
关键逻辑说明:
- 正则匹配部分:
^(\w+(?:_\w+)*)\.txt$^和$确保匹配整个文件名,避免部分匹配导致错误\w+(?:_\w+)*捕获所有下划线分隔的单词组合:\w+匹配第一个单词,(?:_\w+)*是非捕获组,可匹配任意次数的「下划线+单词」结构,完美适配2组、3组、N组的情况
- 替换逻辑部分:
join "_", reverse split /_/, $1split /_/, $1将捕获到的单词块按下划线拆分为数组reverse反转数组顺序join "_"用下划线将反转后的数组重新拼接成字符串
-n参数是测试模式(dry run),只会输出重命名预览不会实际修改文件,确认逻辑正确后可移除该参数执行真实重命名
备选方案(不推荐)
也可以通过全局捕获组实现,但需要考虑潜在的捕获组数量上限,灵活性不如拆分拼接的方式:
rename -n 's/(\w+)(?:_(\w+))*\.txt$/join "_", reverse grep { defined } $1, $2, $3, $4, $5/e' ./*.txt
内容的提问来源于stack exchange,提问作者user26614668
相关产品推荐
相关产品推荐

