Answers:
rename
可让您直接分配给$_
,这是解决此问题的理想选择。尽管我们传递给Perl rename
实用程序的代码参数通常执行匹配和替换(带有s/
),并且以这种方式解决此问题是完全可以接受的,但是在像这样的情况下,实际上您并不需要检查或重用旧文件名的文本。使您几乎可以编写任何 Perl代码,并且不需要将其嵌入到中。我建议使用这样的命令:rename
s/
/e
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
或者,如果您想删除几个字符:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(它可以做得更短,但又不牺牲清晰度。)
这两个命令执行相同的操作。每个都显示将执行的重命名操作。一旦您尝试了一下,并对结果感到满意,请再次运行该-n
选项。由于写的,这将产生的文件名AS01.txt
,AS02.txt
..., ,AS10.txt
,AS11.txt
等等。您可以根据需要修改它们,然后仅-n
在喜欢看到的内容时将其删除。
如果要填充的宽度大于2,则2
用更大的数字替换。例如,如果出于某种原因您想要的文件名如AS00000000000001.txt
,则可以替换%02d
为%014d
。如果您根本不希望填充,尽管那样会使您在以后列出文件时以非数字顺序显示它们!那么您可以%02d
用just 替换%d
。
这是如何运作的?您的shell *
甚至在运行rename
命令之前都会扩展为文件列表。该列表根据您当前的语言环境设置按字典顺序(即,字母顺序)排序。rename
接收文件名作为命令行参数,并按照列出的顺序对其进行处理。该表达式的++$i
计算结果比变量的当前值大一$i
,并且还将变量$i
设置为该新增加的值。该值将传递给sprintf
,以对其进行格式设置并将其放置在其他文本中。该文本直接分配给特殊变量$_
,该变量保存文件名。由于rename
处理文件以它们作为参数传递的顺序排列,因此将对其进行相应的编号。
两者都声明并递增一个计数器变量,并且都sprintf
以基本上相同的方式将计数器的值嵌入到新文件名的其他文本中,该计数器的值在左侧用零填充。(任一答案中有关如何填充零(以及如何更改填充宽度)的信息都同样适用于两者。)之所以如此相似,是因为该较早答案中的方法实际上就是这样做1,但是额外的步骤可解决许多问题,但实际上并非必需。
为了进行比较,这是该答案中的第二个命令的样子,如果将其修改为使用我在此使用的样式(并像在这里所做的那样填充为2的宽度,而不是3):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
该命令之间s/.+/
和其中的部分/e
现在与我在此答案的第一个命令中分配给我的表达式$_
(即,=
运算符右侧的代码)相同。
s/
操作者试图匹配文本(文件名,你的壳由膨胀*
和作为命令行参数时,它运行通过rename
)配有一正则表达式,并且执行替换。/
用作分隔s
表达式的不同部分的定界符。第一部分.+
是正则表达式;它匹配任何一个字符(.
),并且匹配一次或多次(+
)。由于文件名永远不会为空-它们总是至少一个字符长-这是匹配任何1个文件名的一种方法。our $i; sprintf "AS%02d.txt", ++$i
。这将产生新的文件名。通常,一种用于s/
生成文本的方法是(a)替换仅匹配文件名一部分的文本,或者(b)以某种方式基于匹配的文本(例如,它可能会使用特殊的变量,例如$&
扩展为比赛)。但是,在这种情况下,完全不使用匹配的文本。our $i; sprintf "AS%02d.txt", ++$i
将用作文件名,而不是作为代码运行。但是/e
末尾的标志导致该文本被视为Perl源代码并被评估,并使用这样做产生的值(在这种情况下,是Perl内置sprintf
函数的返回值)作为新文件名。虽然我觉得我在这里所示的方法是一个更清晰和更简单的方法针对此问题,使用最多的方法s/
有/e
,这是很好的了解该技术,因为它非常适合于一些其他的文件重命名问题,所有或部分原始文件名已被检查和/或保留。我推荐这个博客帖子由奥利(谁也写这个答案),其中包括一些这样的例子。
1 技术上,有是在行为的差$_ =
命令和s/
/e
命令。在正则表达式中.+
,.
匹配任何字符并不是严格意义上的,因为它不匹配换行符。您很可能不应该在文件名中使用换行符,但是您可以使用文件名,有时偶然地以这种方式命名文件。如果你喜欢它的感觉,对比度输出rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'
到的rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'
。要使.
换行符匹配,请使用s
位于末尾(带有e
)的标志。也就是说,/se
在末尾写而不是/e
。
rename
是prename。这样做可能更好,但您可能需要添加安装说明,以使该答案更有价值。