使用MV重命名多个文件
当您想要重命名多个文件时,事情会变得更加棘手。MV没有处理重命名多个文件的功能。你必须求助于一些巧妙的Bash技巧。如果你知道一些中等级别的命令行FU,这是很好的,但用mv重命名多个文件的复杂性与使用mv重命名单个文件的简便性形成了鲜明的对比。
事情很快就会升级。
假设我们有一个目录,其中包含各种不同类型的文件。其中一些文件的扩展名为“.prog”。我们希望在命令行重命名它们,以便它们具有“.prg”扩展名。
我们如何说服MV为我们做这件事呢?我们来看看这些文件。
ls *.prog -l
这里有一种不需要编写实际的Bash脚本文件的方法。
for f in *.prog; do mv -- "$f" "${f%.prog}.prg"
那管用吗?让我们检查一下文件,看看。
ls *.pr*
所以,是的,它起作用了。它们现在都是“.prg”文件,而目录中没有“.prog”文件。
刚才发生了什么事?
那么长的命令到底做了什么呢?让我们把它分解一下。
for f in *.prog; do mv -- "$f" "${f%.prog}.prg"
第一部分开始一个循环,该循环将依次处理目录中的每个“.prog”文件。
下一部分说明处理将做什么。它将使用mv将每个文件移动到一个新文件。新文件将使用原始文件的名称命名,不包括“.prog”部分。取而代之的是使用新的扩展名“.prg”。
一定有一种更简单的方法
非常肯定。它是RENAME命令。
Rename不是标准Linux发行版的一部分,因此您需要安装它。它在不同的Linux系列中也有不同的名称,但它们的工作方式都是一样的。您只需根据您使用的Linux风格替换相应的命令名即可。
在Ubuntu和Debian派生的发行版中,您安装的重命名如下:
sudo apt-get install rename
在Fedora和RedHat派生的发行版中,您可以这样安装preename。请注意首字母“p”,它代表Perl。
sudo dnf install prename
要在Manjaro Linux中安装它,请使用以下命令。请注意,重命名命令称为perl-rename。
sudo pacman -Syu perl-rename
我们再来一次吧
这一次我们将使用RENAME。我们将回滚时钟,这样我们就有了一组“.prog”文件。
ls *.prog
现在,让我们使用以下命令重命名它们。然后我们将与ls一起检查它是否起作用。如果您使用的不是Ubuntu或Debian派生的Linux,请记住将rename替换为适合您的Linux的命令名。
rename 's/.prog/.prg/' *.prog
ls *.pr*
这样就可以了,它们现在都是“.prg”文件,目录中没有“.prog”文件了。
这次是怎么回事?
让我们分三部分来解释一下这点魔力。
第一部分是命令名rename(对于其他发行版,则为preename或perl-rename)。
最后一部分是*.prog,它告诉Rename对所有“.prog”文件进行操作。
中间部分定义了我们希望在每个文件名上完成的工作。s表示替代。第一个术语(.prog)是RENAME将在每个文件名中搜索的内容,第二个术语(.prg)是它将被替换的内容。
命令的中间部分,即中心表达式,是Perl的“正则表达式”,正是它赋予了重命名命令的灵活性。
更改文件名的其他部分
到目前为止,我们已经更改了文件扩展名,让我们修改文件名的其他部分。
目录中有很多C源代码文件。所有文件名都以“slang_”为前缀。我们可以用ls进行检查。
ls sl*.c
我们将用“sl_”替换所有出现的“slang_”。命令的格式我们已经很熟悉了。我们只是更改了搜索项、替换项和文件类型。
rename 's/slang_/sl_' *.c
这次我们要查找“.c”文件,并搜索“slang_”。只要在文件名中找到“slang_”,就会将其替换为“sl_”。
我们可以通过使用相同的参数重复上面的ls命令来检查该命令的结果:
ls sl*.c
删除文件名的一部分
我们可以通过不使用任何内容替换搜索词来删除文件名的一部分。
ls *.c
rename 's/sl_//' *.c
ls *.c
我们可以从ls命令中看到,我们的“.c”文件都带有“sl_”前缀。让我们干脆把它去掉吧。
重命名命令遵循与前面相同的格式。我们要找的是“.c”文件。搜索项为“sl_”,但没有替换项。两个反斜杠之间没有任何东西意味着什么,一个空字符串。
重命名将依次处理每个“.c”文件。它将在文件名中搜索“sl_”。如果找到它,它将不会被替换为任何内容。换句话说,该搜索词被删除。
第二次使用ls命令确认已经从每个“.c”文件中删除了“sl_”前缀。
限制对文件名的特定部分的更改
让我们使用ls来查看文件名中包含字符串“param”的文件。然后,我们将使用RENAME将该字符串替换为字符串“PARAMETER”。我们将再次使用ls来查看rename命令对这些文件的影响。
ls *param*
rename 's/param/parameter' *.c
ls *param*
发现四个文件的文件名中包含“param”。param.c、param_one.c和param_two.c的名称开头都有“param”。Third_param.c在其名称末尾、扩展名之前有“param”。
rename命令将在文件名中的所有位置搜索“param”,并在所有情况下将其替换为“Parameter”。
第二次使用olls命令向我们表明,这正是已经发生的情况。无论“param”是在文件名的开头还是结尾,它都已被“参数”所取代。
我们可以使用Perl的元字符来改进中间表达式的行为。元字符是表示位置或字符序列的符号。例如,^表示“字符串的开始”,$表示“字符串的结束”,和。指任何单个字符(换行符除外)。
我们将使用字符串元字符开头(^)将搜索限制在文件名的开头。
ls *param*.c
rename 's/^parameter/value/' *.c
ls *param*.c
ls value*.c
列出了我们先前重命名的文件,我们可以看到字符串“参数”位于三个文件名的开头,位于其中一个文件名的末尾。
我们的重命名命令在搜索词“参数”之前使用行开头的“参数”(^)和元字符。这告诉Rename,如果搜索词位于文件名的开头,则只将其视为已找到。如果搜索字符串“PARAMETER”在文件名中的其他位置,它将被忽略。
使用ls检查,我们可以看到,文件名末尾有“参数”的文件名没有被修改,但是名称开头有“参数”的前三个文件名已经用替换项“value”替换了搜索字符串。
重命名的威力在于Perl的威力。Perl的所有威力都可以由您支配。
使用分组进行搜索
Rename还有更多的花招。让我们考虑这样一种情况,即您可能有名称中有相似字符串的文件。它们不是完全相同的字符串,因此简单的搜索和替换在这里不起作用。
在本例中,我们使用ls来检查我们有哪些文件以“string”开头。其中有两个,string.c和hyrole.c。我们可以使用一种称为分组的技术同时重命名这两个字符串。
此重命名命令的中心表达式将在文件名中搜索字符序列为“stri”或“stra”的字符串,其中这些序列后面紧跟“ng”。换句话说,我们的搜索词将查找“String”和“Strang”。替代术语是“砰”。
ls str*.c
rename 's/(stri|stra)ng/bang/' *.c
ls ban*.c
第二次使用工具确认string.c变成了bang.c,stringle.c现在变成了bangle.c。
将翻译与重命名一起使用
RENAME命令可以对文件名执行称为转换的操作。转换的一个简单示例是强制将一组文件名转换为大写。
在下面的rename命令中,请注意我们没有使用s/s来开始中心表达式,我们使用的是y/。这告诉rename我们不是在执行替换;我们是在执行翻译。
a-z术语是一个Perl表达式,表示序列中从a到z的所有小写字符。类似地,A-Z术语表示从A到Z序列中的所有大写字母。
此命令中的中心表达式可以解释为“如果在文件名中找到从a到z的任何小写字母,请将它们替换为从A到Z的大写字符序列中的相应字符。”
要强制所有“.prg”文件的文件名为大写,请使用以下命令:
重命名‘Y/a-z/A-Z/’*.prg
ls *.PRG
ls命令显示所有的“.prg”文件名现在都是大写的。事实上,严格地说,它们不再是“.prg”文件。它们是“.PRG”文件。Linux区分大小写。
我们可以通过颠倒a-z和A-Z项在中心表达式中的位置来反转最后一个命令。
重命名‘y/A-Z/a-z/’*.PRG
ls *.prg
您(我|做)不会在五分钟内学会Perl
掌握Perl是值得花费的时间。但是要开始使用rename命令的省时功能,您根本不需要太多的Perl知识,就可以在功能、简单性和时间上获得巨大的好处。