我怎么知道钻石操作员是否移动到下一个文件?

How can I know if diamond operator moved to the next file?

我在文件中有以下代码 perl_script.pl:

while (my $line = <>) {
    chomp $line;
   // etc. 
}. 

我用超过 1 个文件调用脚本,例如

perl perl_script.pl file1.txt file2.txt

有没有办法知道 $line 是否开始从 file2.txt 等读取?

$ARGV variable

Contains the name of the current file when reading from <>

您可以保存名称并在每一行上进行测试以查看它是否更改,并在更改时更新。

如果它真的只是关于获取特定文件,正如问题似乎所说的那样,那么它更容易,因为您还可以使用包含命令行参数的 @ARGV 直接测试需要名字。


另一种选择是使用 eof(不带括号的形式!)来测试文件结尾,这样您就会知道下一个文件将在下一次迭代中出现——因此您将还需要某种旗帜。

对此的一个变体是明确关闭每个文件末尾的文件句柄,以便 $. 为每个新文件重置,<> 通常不会发生这种情况,然后$. == 1 是新打开文件的第一行

while (<>) { 
    if ($. == 1) { say "new file: $ARGV" }
} 
continue { 
    close ARGV if eof;
} 

perldoc -f eof 中记录的一个有用技巧是 while (<>) 循环中的 } continue { close ARGV if eof } 习语。这会导致 $.(输入行号)在 ARGV 迭代的文件之间被重置,这意味着它将始终是 1 在给定文件的第一行。

有一个 eof 技巧,但祝你好运,向人们解释。我经常发现我也想用旧文件名做点什么。

根据您想执行的操作,您可以跟踪您正在访问的文件名 继续工作,以便您可以识别何时更改为新文件。那样 你同时知道这两个名字:

use v5.10;
my %line_count;
my $current_file = $ARGV[0];
while( <> ) {
    if( $ARGV ne $current_file ) {
        say "Change of file from $current_file to $ARGV";
        $current_file = $ARGV;
        }

    $line_count{$ARGV}++
    }

use Data::Dumper;
say Dumper( \%line_count );

现在你看到文件什么时候改变了,你可以使用$ARGV

Change of file from cache-filler.pl to common.pl
Change of file from common.pl to wc.pl
Change of file from wc.pl to wordpress_posts.pl
$VAR1 = {
          'cache-filler.pl' => 102,
          'common.pl' => 13,
          'wordpress_posts.pl' => 214,
          'wc.pl' => 15
        };

根据我在做什么,我可能不会让钻石操作员做所有事情 工作。这让我可以更好地控制正在发生的事情, 我该如何回应:

foreach my $arg ( @ARGV ) {
    next unless open my $fh, '<', $arg;
    while( <$fh> ) { 
        ...
        }
    }