我希望能够重命名具有不同扩展名的perl文件,只要文件名相同即可。例如,
ExampleFile.txt
ExampleFile.html
FirstFile.txt
我希望我可以在Linux上使用Perl单行代码来更改包含字符串“ ExampleFile”作为名称的文件,而不管其扩展名是“ FinalFile”如何,但不能更改任何其他文件(例如“ FirstFile”)。我一直在研究rename
,但似乎无法弄清楚如何将其用于任何文件扩展名。
执行rename "$findstring.*", "$replacestring.*";
之类的操作似乎无效,因为perl无法识别*
来表示任何文件扩展名。
这里是一个示例代码,可以显示我的问题。
#!/usr/bin/perl
use strict;
use warnings;
my $findstring = "ExampleFile";
my $replacestring = "FinalFile";
rename ("myDir/$findstring.*", "myDir/$replacestring.*");
答案 0 :(得分:7)
有一个工具rename
,我相信大多数系统都附带该工具(例如,CentOS7拥有)
手册页简短,带有简介和说明
重命名 [选项] 表达式 替换 文件 ... >
重命名将通过用 replacement 替换名称中首次出现的 expression 来重命名指定的文件。
后面是一个示例,它不完全是基本示例,但希望它清晰而有用。
以您的情况
rename ExampleFile NewName ExampleFile.*
应该是您所需要的。
另一种方法是在Perl中完成
perl -MFile::Basename -MFile::Copy=move -wE'
for (@ARGV) {
($name, $path, $ext) = fileparse($_, qr/\.[^.]*/);
say "Rename: $_ to $path/NewName$ext";
#move $_, "$path/NewName$ext"
}
' ExampleFile*
一旦您用ExampleFile.*
取消注释,这将把所有NewName
重命名为具有相同扩展名的move
。就目前而言,它仅会打印将要执行的操作,因此可以先对其进行全面测试。
它使用File::Basename :: fileparse
查找在命令行上提交的每个文件的文件名组成部分,然后使用File::Copy重命名每个文件。还有其他解析文件名和其他模块的方法。
这是用于快速复制粘贴测试的命令行程序;请将其转换为脚本,并进行适当的错误检查。然后,您可以使用Getopt::Long来创建一个具有更好调用功能的实用程序。
答案 1 :(得分:3)
我同意@zdim的回答,并希望添加一个可能的说明。我认为您可能会将正则表达式替换与通配混淆。 Globbing 为您提供文件名列表,因此您无需指定扩展名。然后,您可以使用 regex 构建新名称。使用rename(1)是最简单的方法,但是如果必须使用单行代码,则在Perl 5.14+上可以使用类似的方法-
perl -MFile::Glob -MFile::Copy -E 'move($_, s/^ExampleFile/FinalFile/r) foreach <ExampleFile.*>'
<...>
是全局名称,它列出了匹配的文件名。然后分别move(, s///)
进行重命名。
在问题的示例代码中,您在正则表达式中使用.*
,但似乎您希望在全局中使用它。在@zdim的答案中,shell glob和Perl重命名。
编辑,相应的代码应该可以正常工作(未经测试):
use 5.014;
use File::Glob ':bsd_glob'; use File::Copy;
move($_, s/^\Q$findstring/$replacestring/r) foreach bsd_glob("$findstring.*");
编辑2 ,不使用File::Glob
:
use 5.014;
use File::Copy;
move($_, s/^\Q$findstring/$replacestring/r) foreach <$findstring.*>;
内置的<foo>
运算符在列表上下文中遍历foo
并返回匹配项列表。
答案 2 :(得分:0)
您可以尝试直接应用重命名功能
示例
使用相同的代码可能会起作用