使用Perl重命名目录中的文件

Joh*_*an1 7 directory perl rename file

我想要一个目录和所有电子邮件(*.msg)文件,删除开头的'RE'.我有以下代码但重命名失败.

opendir(DIR, 'emails') or die "Cannot open directory";
@files = readdir(DIR);
closedir(DIR);

for (@files){
    next if $_ !~ m/^RE .+msg$/;
    $old = $_;
    s/RE //;
    rename($old, $_) or print "Error renaming: $old\n";
}
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 10

如果您的./emails目录包含以下文件:

1.msg
2.msg
3.msg
Run Code Online (Sandbox Code Playgroud)

那么你@files会看起来像('.', '..', '1.msg', '2.msg', '3.msg'),但你rename要喜欢的名字'emails/1.msg','emails/2.msg'等等.所以,你可以chdir重命名之前:

chdir('emails');
for (@files) {
    #...
}
Run Code Online (Sandbox Code Playgroud)

您可能也想检查chdir返回值.

或者自己添加目录名称:

rename('emails/' . $old, 'emails/' . $_) or print "Error renaming $old: $!\n";
# or rename("emails/$old", "emails/$_") if you like string interpolation
# or you could use map if you like map
Run Code Online (Sandbox Code Playgroud)

您可能希望使用以下命令组合目录读取和过滤grep:

my @files = grep { /^RE .+msg$/ } readdir(DIR);
Run Code Online (Sandbox Code Playgroud)

甚至这个:

opendir(DIR, 'emails') or die "Cannot open directory";
for (grep { /^RE .+msg$/ } readdir(DIR)) {
    (my $new = $_) =~ s/^RE //;
    rename("emails/$_", "emails/$new") or print "Error renaming $_ to $new: $!\n";
}
closedir(DIR);
Run Code Online (Sandbox Code Playgroud)


eph*_*ent 5

你似乎在假设glob行为而非readdir行为.

底层readdir系统调用只返回目录中的文件名,并包含两个条目....这继续readdir了Perl中的功能,只是为了更详细地介绍一下mu的答案.

或者,readdir如果您正在收集数组中的所有结果,那么使用它并没有多大意义.

@files = glob('emails/*');
Run Code Online (Sandbox Code Playgroud)