如何在Perl的for循环中重命名文件

4
我正在运行一个Perl脚本,试图完成如下的文件重命名...
我有一个文件夹中包含一些*.ru.jp文件和其他不相关的文件。我想用一个计数器变量作为编号来重命名这些文件。
在Bash中,我会这样做...
for i in $(ls *.ru.jp); do x=${i%%.*}; mv $i  "$x"t"$counter".ru.jp ;done

例如,如果计数器为1,则myfile.ru.jp将被重命名为myfilet1.ru.jp。 "t"只是一个命名,表示t1,t2等。最终会有一个外部循环标记mafilet2.ru.jp等,并且随着计数器变量的增加而增加。
我想知道如何编写和表示类似于Perl脚本中的for循环?
谢谢。
-乔伊
6个回答

8
perl -e 'for $old (@ARGV) {
           ++$counter;
           if (($new=$old) =~ s/(\.ru\.jp)\z/t$counter$1/) {
             rename $old => $new or warn "$0: rename: $!\n";
           }
         }' *.ru.jp

当你写下 push $element => @list 时会发生什么呢?哎呀,错了。要小心使用胖逗号。 - jrockway

7
您可以使用Perl的文件glob和内置的重命名功能rename,如下所示:
use warnings;
use strict;

my $i = 1;
for (<*.ru.jp>) {
    my $file = $_;
    s/\.ru\.jp$//;
    my $new = $_ . 't'. $i . '.ru.jp';
    rename $file, $new or die "Can not rename $file as $new: $!";
    $i++;
}

1

我尝试了这个,似乎可以完成工作:

#! /usr/bin/perl

my $count = 0;
for (<*.ru.jp>)
{
        $count++;
        /(.+)\.ru\.jp/;
        rename $_, $1 . "t" . $count . ".ru.jp";
}

3
永远不要无条件地使用捕获变量($1$2 等),匹配后使用 && 代替分号。我知道在这种特定情况下这似乎是小题大作,但养成这种习惯可以避免你追寻棘手的 bug。 - Greg Bacon
谢谢您的建议 :) 那么,您更喜欢这样的代码吗?:/(.+).ru.jp/ && rename $_, $1 . "t" . $count . ".ru.jp"; - Grimmy
是的,或者强调将其放在前面重命名:rename ... if /(.+)\.ru\.jp/。两者都忽略从rename返回的值,因此任何失败都将非常安静。你可以编写/.../ && (rename ... || warn ...);,但那似乎有点太聪明了。另一个重要的习惯是始终检查系统调用的返回值,例如renameopenunlink等。即使printclose也可能会失败,因此在编写重要代码时要检查它们。 - Greg Bacon

1
my $counter=0;
while(my $file=<*.ru.jp>){
    $counter++;
    my ($front,$back) = split /\./,$file,2;
    $newname="$front$counter".".t."."$back\n";
    rename $file $newname;
}

1
$count = 1;
for (<*.ru.jp>)
{
        ($filename)=(/^(.*?)\.ru.jp$/);
        rename $_,$filename."t".$count++.".ru.jp";
}

1
use strict;
my $c=0;
rename("$1.ru.jp", "$1" . $c++ . ".ru.jp") while <*.ru.jp> =~ /(.+).ru.jp/;

最好使用 strict;同时也要使用 warnings。 - Brian Carlton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接