考虑这个文件列表:
$ touch index-{1,2,3,4,5,6,7,8,9}.txt
Run Code Online (Sandbox Code Playgroud)
如果我想将它们向下移动以便它们从零开始,则相对容易:
$ rename --verbose 's/^index-([1-9])\.txt$/$1/; $_="index-" . ($_ - 1) . ".txt"' index-*.txt
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为man bash
指定 globs 按字母顺序排序,所以它会在重命名index-1.txt
为index-0.txt
之前重命名index-2.txt
为index-1.txt
。
如果你想向上移动,或者如果数字有不同的长度,这会崩溃:
$ touch index-{10,11}.txt
$ rename --verbose 's/^index-([0-9]+)\.txt$/$1/; $_="index-" . ($_ + 1) . ".txt"' index-*.txt
index-10.txt not renamed: index-11.txt already exists
index-11.txt renamed as index-12.txt
index-1.txt not renamed: index-2.txt already exists
Run Code Online (Sandbox Code Playgroud)
可能的长期修复:
rename
选项来尝试重新排序操作,直到没有冲突。rename
将文件移动到临时目录的选项,然后使用新名称将它们移回。rename
分两步重命名文件的选项,在第一步中使用不会与原始名称或新名称冲突的唯一名称。有没有一种简单的方法可以解决这个问题?
@l0b0 的解决方案重写以获得更好的鲁棒性:
printf '%s\0' index-*.txt |
sort --zero-terminated --field-separator - --key 2rn |
xargs -0r rename --verbose '
s/^index-([0-9]+)\.txt$/$1/;
$_="index-" . ($_ + 1) . ".txt"'
Run Code Online (Sandbox Code Playgroud)
请随意包含在您的解决方案中,之后我将删除我的答案。
请注意,@l0bo 的解决方案是 GNU 特定的,而不是 Unix(GNU's Not Unix)。
归档时间: |
|
查看次数: |
1802 次 |
最近记录: |