如何从命令行逐个按顺序批量重命名多个文件?

如何将文件重命名为以下名称
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
7个回答

Ubuntu自带的rename工具在这方面非常强大。你可以嵌入一些小的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' *

... 但这很容易扩展。


我不知道有任何一个命令或工具可以做到这一点,但是用一个简单的循环就足够容易实现了。
N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done

为了改进@Oli的答案,由Aristotle Pagaltzis开发的版本1.600的rename工具实际上内置了一个计数器$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

rename让你可以直接赋值给$_,这对于这个问题来说是理想的。

虽然我们传递给Perl rename实用程序的代码参数通常执行匹配和替换(使用s/),并且以这种方式解决这个问题是完全可接受的,但在像这样的情况下,实际上不需要这样做,因为您并没有检查或重用旧文件名的文本。 rename允许您编写几乎任何 Perl 代码,而且不需要嵌入在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”替换为“%d”。 这是如何工作的?在运行rename命令之前,你的shell会将你的shell扩展*转换为一个文件列表。该列表根据你当前的区域设置按字典顺序(即按字母顺序)排序。rename将文件名作为命令行参数接收并按照它们的顺序进行处理。表达式++$i的值是变量$i的当前值加一,并将该新增后的值赋给变量$i。这个值被传递给sprintf,它对其进行格式化并将其放入其他文本中。这段文本直接赋值给特殊变量$_,它保存着文件名。由于rename按照参数传递的顺序处理文件,它们会相应地编号。
你可能已经注意到了与Oli's answer的相似之处! 两者都声明并递增一个计数器变量,并且都以基本相同的方式使用sprintf将该计数器的值嵌入到新文件名的其他文本中,左侧用零填充。(关于如何用零填充和更改填充宽度的信息在这两个答案中都适用。)它们之所以如此相似,是因为那个旧答案中的方法实际上只是在做这个1,但还有一些额外的步骤,对于许多问题来说很有用,但对于这个问题来说实际上并不必要。 为了比较,如果修改第二个命令以使用我在这里使用的样式(并且将填充宽度修改为2,就像我在这里做的那样),它看起来是这样的:
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
在该命令中,位于s/.+//e之间的部分现在与我在本答案中第一个命令中分配给$_的表达式相同(即,等号操作符右侧的代码)。
  • s/ operator 尝试将文本(由您的shell从*扩展并作为命令行参数传递给rename运行时的文件名)与正则表达式匹配,并执行替换。 / 用作分隔符,以分隔s 表达式的不同部分。第一部分.+ 是正则表达式;它匹配任何字符 (.), 并且这样做一次或多次 (+)。由于文件名永远不会为空-它们至少有一个字符长-这是匹配任何文件名的一种方式。
  • 然后它从每个匹配中生成文本-也就是说,从每个完整的文件名中-由our $i; sprintf "AS%02d.txt", ++$i 组成。这将产生新的文件名。通常,人们使用s/来生成文本,该文本要么是(a)替换了仅匹配文件名的一部分的文本,要么是(b)基于某种方式中的匹配文本(例如,它可能使用像$&这样的特殊变量,该变量扩展为匹配)。但是,在这种情况下,匹配的文本根本没有被使用。
  • 通常,替换的文本our $i; sprintf "AS%02d.txt", ++$i将用作文件名,而不是作为代码运行。但是,末尾的/e标志会导致该文本被视为Perl源代码并进行评估,并使用通过这样做产生的值(在本例中,是Perl内置的sprintf函数的返回值)作为新的文件名。
虽然我认为我在这里展示的方法比使用s//e的任何方法都更清晰简单,但了解这种技术是很好的,因为它非常适用于许多其他文件重命名问题,其中需要检查和/或保留原始文件名的全部或部分内容。我推荐阅读这篇博文,作者是Oli(他也写了那个答案),其中包含一些相关示例。

1 从技术上讲,$_ = 命令和 s/ /e 命令的行为是有区别的。在正则表达式 .+ 中,严格来说 . 并不匹配任何字符,因为它不能匹配换行符newline。虽然你很可能不会使用带有换行符的文件名,但有时候一个文件会意外地以这种方式命名。如果你感兴趣的话,可以对比一下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


尽管 OP 需要一个命令行选项,但它也可以在 Nautilus 的 GUI 选项中找到,并且非常容易。 选择所有所需的文件,然后按 F2。有一个名为“自动编号”的选项。您可以将其附加到所需的文本中。

假设您想要重命名的文件位于 ~/Adir 文件夹中,并且这些是该文件夹中唯一的文件,那么:
n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done
这个脚本将查看~/Adir中的每个文件,并将其重命名为AS1.txt, AS2.txt, ...,如果文件不存在(不会有任何覆盖)。所以你应该确保这些是~/Adir中唯一的文件。sort命令只是为了保持文件的初始顺序。

您可以这样做:
x=1; for k in AS*; do y=$((x++));  echo "mv ${k} ${k:0:2}$y.txt"; done
如果你想保存扩展名,请使用以下方法(预测试):
x=1; for k in AS*; do y=$((x++));  echo "mv ${k} ${k:0:2}$y.${k#*.}"; done
如果预测试通过,那么删除回显,代码将会运行成功。
x=1; for k in AS*; do y=$((x++));  mv ${k} ${k:0:2}$y.txt; done
将以下代码更改为保存扩展名的版本(删除“echo”语句,然后代码将正常运行):
x=1; for k in AS*; do y=$((x++));  mv ${k} ${k:0:2}$y.${k#*.}; done
  • ${k:0:2} --> 文件的前两个字母
  • ${k#*.}- --> 文件的扩展名

我自己也遇到过类似的情况,并且解决了它。 我的文件就是这样的:
 1-6-4-20.txt       onar.mol2  replace.py  z.out       z__06.mol2  z__09.mol2  z__12.mol2  z__15.mol2  z__18.mol2  z__27.mol2  z__30.mol2  z__33.mol2  z__36.mol2
make_com_files.py  pt.dat     valid.txt   z.xyz       z__07.mol2  z__10.mol2  z__13.mol2  z__16.mol2  z__25.mol2  z__28.mol2  z__31.mol2  z__34.mol2  z__37.mol2
makepymol.py       pymol.pml  x.py        z__05.mol2  z__08.mol2  z__11.mol2  z__14.mol2  z__17.mol2  z__26.mol2  z__29.mol2  z__32.mol2  z__35.mol2
请注意,没有"z_01.mol2"、"z_02.mol2"、"z_03.mol2"、"z_04.mol2"以及"z_19.mol2"、"z_20.mol2"等等这些文件,所以我的z文件并不是按顺序排列的。我无法通过省略"z_*"前缀来解决这个问题。而且,我还有"onar.mol2"这个文件。 以下是我的解决方案: 使用"echo"进行预测试,看看是否能正常工作:
 x=1; for k in *.mol2; do y=$((x++));  echo "mv ${k%%.*}.mol2 $y.mol2"; done

输出:

mv onar.mol2 1.mol2
mv z__05.mol2 2.mol2
mv z__05.mol2 2.mol2
    mv z__06.mol2 3.mol2
    mv z__07.mol2 4.mol2
    mv z__08.mol2 5.mol2
    mv z__09.mol2 6.mol2
    mv z__10.mol2 7.mol2
    mv z__11.mol2 8.mol2
    mv z__12.mol2 9.mol2
    mv z__13.mol2 10.mol2
    mv z__14.mol2 11.mol2
    mv z__15.mol2 12.mol2
    mv z__16.mol2 13.mol2
    mv z__17.mol2 14.mol2
    mv z__18.mol2 15.mol2
    mv z__25.mol2 16.mol2
    mv z__26.mol2 17.mol2
    mv z__27.mol2 18.mol2
    mv z__28.mol2 19.mol2
    mv z__29.mol2 20.mol2
    mv z__30.mol2 21.mol2
    mv z__31.mol2 22.mol2
    mv z__32.mol2 23.mol2
    mv z__33.mol2 24.mol2
    mv z__34.mol2 25.mol2
    mv z__35.mol2 26.mol2
    mv z__36.mol2 27.mol2
    mv z__37.mol2 28.mol2
似乎正确,那么我可以将这个作为我的目标的命令使用(通过删除回声):
x=1; for k in *.mol2; do y=$((x++));  mv ${k%%.*}.mol2 $y.mol2; done
结果:ls -ln:
-rwxrwxrwx 1 0 0     1695 Nov 18 12:07 1-6-4-20.txt
-rwxrwxrwx 1 0 0     1813 Nov 18 13:27 1.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 10.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 11.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 12.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 13.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 14.mol2
-rwxrwxrwx 1 0 0     2784 Nov 18 13:27 15.mol2
-rwxrwxrwx 1 0 0     2785 Nov 18 13:27 16.mol2
-rwxrwxrwx 1 0 0     2785 Nov 18 13:27 17.mol2
-rwxrwxrwx 1 0 0     2786 Nov 18 13:27 18.mol2
-rwxrwxrwx 1 0 0     2786 Nov 18 13:27 19.mol2
-rwxrwxrwx 1 0 0     2781 Nov 18 13:27 2.mol2
-rwxrwxrwx 1 0 0     2787 Nov 18 13:27 20.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 21.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 22.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 23.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 24.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 25.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 26.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 27.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 28.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 3.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 4.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 5.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 6.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 7.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 8.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 9.mol2
-rwxrwxrwx 1 0 0     1383 Nov 17 12:27 make_com_files.py
-rwxrwxrwx 1 0 0     5687 Nov 17 16:34 makepymol.py
-rwxrwxrwx 1 0 0     1206 Nov 17 11:36 pt.dat
-rwxrwxrwx 1 0 0      964 Nov 18 13:29 pymol.pml
-rwxrwxrwx 1 0 0     2288 Nov 18 13:27 replace.py
-rwxrwxrwx 1 0 0     1284 Nov 18 13:07 valid.txt
-rwxrwxrwx 1 0 0     3809 Nov 18 12:37 x.py
-rwxrwxrwx 1 0 0 19622334 Nov 18 04:11 z.out
-rwxrwxrwx 1 0 0    34717 Nov 18 12:37 z.xyz
    enter code here
额外: 如果我想要将我的文件命名为00001.mol200002.mol2等等,我也可以添加这个命令:
rename 's/\d+/sprintf("%05d",$&)/e' *.mol2
这是我的mol2文件:
-rwxrwxrwx 1 0 0     1813 Nov 18 13:27 00001.mol2
-rwxrwxrwx 1 0 0     2781 Nov 18 13:27 00002.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 00003.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00004.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00005.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00006.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00007.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 00008.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 00009.mol2
-rwxrwxrwx 1 0 0     2782 Nov 18 13:27 00010.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00011.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00012.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00013.mol2
-rwxrwxrwx 1 0 0     2783 Nov 18 13:27 00014.mol2
-rwxrwxrwx 1 0 0     2784 Nov 18 13:27 00015.mol2
-rwxrwxrwx 1 0 0     2785 Nov 18 13:27 00016.mol2
-rwxrwxrwx 1 0 0     2785 Nov 18 13:27 00017.mol2
-rwxrwxrwx 1 0 0     2786 Nov 18 13:27 00018.mol2
-rwxrwxrwx 1 0 0     2786 Nov 18 13:27 00019.mol2
-rwxrwxrwx 1 0 0     2787 Nov 18 13:27 00020.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00021.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00022.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00023.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00024.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00025.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00026.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00027.mol2
-rwxrwxrwx 1 0 0     2788 Nov 18 13:27 00028.mol2
-rwxrwxrwx 1 0 0     1695 Nov 18 12:07 1-6-4-20.txt
-rwxrwxrwx 1 0 0     1383 Nov 17 12:27 make_com_files.py
-rwxrwxrwx 1 0 0     5687 Nov 17 16:34 makepymol.py
-rwxrwxrwx 1 0 0     1206 Nov 17 11:36 pt.dat
-rwxrwxrwx 1 0 0      964 Nov 18 13:29 pymol.pml
-rwxrwxrwx 1 0 0     2288 Nov 18 13:27 replace.py
-rwxrwxrwx 1 0 0     1284 Nov 18 13:07 valid.txt
-rwxrwxrwx 1 0 0     3809 Nov 18 12:37 x.py
-rwxrwxrwx 1 0 0 19622334 Nov 18 04:11 z.out
-rwxrwxrwx 1 0 0    34717 Nov 18 12:37 z.xyz