我在 Linux 机器上有一组带有前缀的文件,比如“pre_”,我只想通过删除它来重命名所有这些文件。这是我编写的 perl 代码,它不会引发任何错误,但工作尚未完成。
#!/usr/bin/perl -w
my @files = `ls -1 | grep -i \"pre_.*\"`;
foreach $file ( @files )
{
my @names = split(/pre_/, $file);
my $var1 = $names[1];
'mv "$file" "$var1"';
}
你没有执行任何事情。当您将某些内容放在单引号 (
''
) 中时,这只是一个字符串,因此'mv "$file" "$var1"'
不是命令,它是一个字符串并且不执行任何操作。字符串本身就是一个真实的陈述。为了执行该命令,您需要使用:(不会
引入命令注入漏洞)。system("mv '$file' '$var1'")
但没有必要,
perl
有一个rename()
功能,所以你可以这样做:接下来,您确实不应该解析 的输出
ls
,这是一个非常糟糕的主意并且很脆弱。在 Perl(或任何其他编程语言)中也完全没有必要。如果你想匹配当前目录中包含该字符串的所有文件pre_
(这就是你grep
所做的——你不需要grep
,顺便说一句,你可以只使用ls -d -- *pre_*
),你可以glob()
这样使用:因此,将所有这些放在一起,这就是您想要做的:
但这确实不是一个好主意。如果您有两个具有相同前缀(例如
pre_file1
和apre_file1
)的文件,则第一个文件将被第二个文件覆盖,因为在本示例中,两个文件都将被重命名为,file1
因为您的命令将删除pre_
其之前的所有内容。因此,您可以添加警告并跳过这些文件:当然,这一切都是在重新发明轮子。你可以直接安装
perl-rename
(在 Debian、Ubuntu 等上运行apt install rename
,在其他系统上它可能被称为prename
或perl-rename
),然后你就可以这样做(虽然这不是不区分大小写,但它只查找包含 的文件pre_
):导致只打印它会做什么,而不实际重命名
-n
。rename
一旦确定重命名按预期工作,请再次运行该命令,而无需-n
实际重命名文件。在这里,shell 将所有(非隐藏)文件传递给
rename
并将忽略代码未更改rename
名称的文件。您还可以告诉 shell 仅通过in 、 in 传递包含不区分大小写的perl
文件名,在、或或 use中全局设置选项。pre_
./~(i)*pre_*
ksh93
./(#i)*pre_*
zsh -o extendedglob
nocaseglob
bash
zsh
yash
./*[pP][rR][eE]_*
您需要的工具已经存在
rename
(也取决于您的发行版perl-rename
或prename
)用于
-n
试运行和-v
列出重命名。注意:不要与工作
rename
方式不同的命令混淆util-linux
。...其他重命名替代方案(而不是“重新发明轮子”)是...
mmv
像这样使用:或者在 Z Shell(
zsh
) 中使用其内置函数,zmv
如下所示:注意:
-n
在上述两种情况下都是为了安全的试运行...当对输出感到满意时,将其删除或用-v
(用于冗长)替换它,以便实际的重命名将会发生。