如何利用正则表达式捕获组\1作为整数变量实现文件批量重命名
文件重命名:给文件名中的数字自增1并拼接格式
需求背景
有一批文件名格式是 some_text some_number.ext,比如:
blabla 1.ext blabla 22.ext blabla 323.ext
需要把它们重命名成 some_text some_number-some_number+1.ext 的格式,也就是:
blabla 1-2.ext blabla 22-23.ext blabla 323-324.ext
踩坑的错误脚本
之前试了下面这个脚本,但结果不对:
for fn in *; do new_fn=$(echo $fn|sed 's/ \([0-9]*\)/ \1-\1\++/'); mv $fn $new_fn; done
得到的错误结果是:
blabla 1-1++.ext blabla 22-22++.ext blabla 323-323++.ext
问题出在Sed只能做字符串替换,没法直接对捕获到的数字做加法运算,得换个思路。
可行的解决方案
方法1:用Bash自带功能直接处理
Bash本身就能拆分字符串和做整数运算,不用额外工具,简单直接:
for fn in *.ext; do # 先把文件名拆出数字部分 temp=${fn%.*} # 去掉后缀 .ext,得到类似 "blabla 1" 的字符串 num=${temp##* } # 删掉最后一个空格前面的内容,只剩数字 next_num=$((num + 1)) # 数字自增1 # 替换原文件名里的数字为 "数字-自增后数字" new_fn=${fn/$num/$num-$next_num} # 执行重命名,-- 用来避免文件名开头带减号时出错 mv -- "$fn" "$new_fn" done
方法2:用Awk同时处理匹配和运算
Awk擅长处理文本匹配和数值计算,一步到位:
for fn in *.ext; do new_fn=$(echo "$fn" | awk '{ # 匹配文件名末尾的数字部分 match($0, /([0-9]+)\.ext$/, arr); num = arr[1]; # 替换成目标格式,Awk会自动把字符串转成数值做加法 sub(/[0-9]+\.ext$/, num "-" (num+1) ".ext"); print $0 }') mv -- "$fn" "$new_fn" done
方法3:Sed配合Shell执行运算(适合非要用Sed的场景)
如果坚持要用Sed,可以让Sed生成完整的重命名命令,再交给Shell处理运算:
ls *.ext | sed -n 's/\(.* \)\([0-9]*\)\(\.ext\)/mv -- "\1\2\3" "\1\2-$((\2+1))\3"/p' | bash
原理是Sed先构造出包含加法运算的mv命令,再通过管道传给bash执行,这样Shell会解析$((\2+1))完成数字自增。注意这种方法要确保文件名里没有特殊符号(除了空格),否则可能出问题。
内容的提问来源于stack exchange,提问作者Misha
相关产品推荐
相关产品推荐

