我想批量重命名文件名
A-B-C#2-D.wav
转向A-B-C#1-D.wav
.例如:
A-B-C#2-D.wav
A-B-C#8-G.wav
A-B-C6-E.wav
变成
A-B-C#1-D.wav
A-B-C#7-G.wav
A-B-C5-E.wav
所以第三个子串中的数字应该减一。 (#
是文件名的一部分,而不是注释;带或不带文件名#
都是可能的。)
答案1
和zsh
:
autoload zmv # best in ~/.zshrc
zmv -n '(*[^0-9])(<1->)(*.wav)(#qn)' '$1$(($2-1))$3'
(如果满意则删除-n
)
用于(#qn)
对列表进行数字排序以便A-B-C#9-D.wav
重命名前 A-B-C#10-D.wav
例如。
但是,如果同时存在 aA-B-C#9-D.wav
和A-B-C#10-D.wav
,zmv
将标记一个文件将被重命名为现有文件的名称并中止该命令。您需要添加-f
选项才能仍然强制执行它。
或者使用 zsh (对于数字全局顺序)和perl
's 重命名:
rename -n 's/\d+/$&-1/e' ./*[1-9]*.wav(#qn)
-f
(与某些变体相同的警告和相同的选项rename
)。
答案2
使用特定于 bash 的循环(用于正则表达式测试条件=~
):
for file in ?-?-*-?.wav
do
[[ $file =~ ^([^[:digit:]]+)([[:digit:]]+)(-.\.wav)$ ]] &&
echo mv -- "$file" "${BASH_REMATCH[1]}$((10#${BASH_REMATCH[2]} - 1))${BASH_REMATCH[3]}"
done
这使用通配符来选取所需的wav
文件;匹配的文件将在破折号之间和.wav
末尾之前有一个字符(字母)。每个文件名都通过正则表达式运行,将其分为三部分:
^([^[:digit:]]+)
——引导部分;一切直到但不包括第一个数字([[:digit:]]+)
-- 数字(-.\.wav)
-- 尾随部分
如果匹配成功,则我们使用前导部分、数字减一和尾随部分重命名该文件。
echo
当输出看起来正确时删除。