如何从命令行顺序重命名多个文件?


15

如何如下重命名文件

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

重新命名

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt

Answers:


22

renameUbuntu附带的工具在这种情况下非常热门。您可以像这样嵌入一些Perl表达式:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

那只会告诉你它会做什么。删除-n使其成为实弹演习。

这基本上是通过粗定义一个变量并在我们命中的每个文件中增加它来实现的。如果您要拥有10个以上的文件,建议您在中使用一些零填充sprintf。以下是最合适的999

rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *

...但这很容易扩展。


4

我不知道会执行此操作的单个命令或实用程序,但是使用一个简单的循环就足够容易了:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done

3

为了提高@奥利的答案,该rename工具版本1.600亚里士多德Pagaltzis居然内置了一个柜台,$N

所以你所需要的就是

rename 's/AS.*/AS$N/' *

安装,

  1. brew install rename下载脚本
  2. 将其保存到系统路径上的目录(通常为/usr/local/bin/brew/usr/bin

3
这似乎是名称相同的其他工具。Ubuntu的默认名称rename是prename。这样做可能更好,但您可能需要添加安装说明,以使该答案更有价值。
奥利(Oli)

1
@Oli好电话!更新。
Atav32

2

rename可让您直接分配给$_,这是解决此问题的理想选择。

尽管我们传递给Perl rename实用程序的代码参数通常执行匹配和替换(带有s/),并且以这种方式解决此问题完全可以接受的,但是在像这样的情况下,实际上您并不需要检查或重用旧文件名的文本。使您几乎可以编写任何 Perl代码,并且不需要将其嵌入到中。我建议使用这样的命令:renames/ /e

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

或者,如果您想删除几个字符:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(它可以做得更短,但又不牺牲清晰度。)

这两个命令执行相同的操作。每个都显示将执行的重命名操作。一旦您尝试了一下,并对结果感到满意,请再次运行该-n选项。由于写的,这将产生的文件名AS01.txtAS02.txt..., ,AS10.txtAS11.txt等等。您可以根据需要修改它们,然后仅-n在喜欢看到的内容时将其删除。

如果要填充的宽度大于2,则2用更大的数字替换。例如,如果出于某种原因您想要的文件名如AS00000000000001.txt,则可以替换%02d%014d。如果您根本不希望填充,尽管那样会使您在以后列出文件时以非数字顺序显示它们!那么您可以%02d用just 替换%d

这是如何运作的?您的shell *甚至在运行rename命令之前都会扩展为文件列表。该列表根据您当前的语言环境设置按字典顺序(即,字母顺序)排序。rename接收文件名作为命令行参数,并按照列出的顺序对其进行处理。该表达式的++$i计算结果比变量的当前值大一$i,并且还将变量$i设置为该新增加的值。该值将传递给sprintf,以对其进行格式设置并将其放置在其他文本中。该文本直接分配给特殊变量$_,该变量保存文件名。由于rename处理文件以它们作为参数传递的顺序排列,因此将对其进行相应的编号。


您可能已经注意到与Oli的答案相似!

两者都声明并递增一个计数器变量,并且都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


0

假设要重命名的文件位于中~/Adir,并且这是此文件夹中仅有的文件,则:

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

该脚本将查看其中的每个文件,如果文件不存在(不会有任何改写)~/AdirAS1.txt, AS2.txt, ...则将其重命名为。因此,您应该确保这些是中的唯一文件~/Adir。该sort命令只是在您希望文件保持初始顺序的情况下。


0

尽管OP需要命令行选项,但它在Nautilus中也可以作为GUI选项使用,并且非常简单。

选择所有必需的文件,然后按F2。有一个选项叫做自动编号。您可以将其附加到所需的文本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.