一次读取一个ARGV文件

时间:2012-07-30 14:01:22

标签: perl

我希望用ARGV指定的每个(小)文件都在自己的数组中读取。如果我不测试$ARGV<>会将所有文件都放在一个表中。是否有更好/更短/更简单的方法呢?

# invocation: ./prog.pl *.txt

@table = ();
$current = "";
while (<>)
{
  if ($ARGV ne $current)
  {
    @ar = ();
    $current = $ARGV;
    if ($current)
    {
      push @table, \@ar;
    }
  }
  push @ar;
}

4 个答案:

答案 0 :(得分:7)

eof函数可用于检测每个文件的结尾:

#!/usr/bin/env perl

use strict;
use warnings;

my @files;
my $file_ctr = 0;
while (<>) {
    chomp;
    push @{ $files[$file_ctr] }, $_;
}
continue { $file_ctr++ if eof }

相关文件:

  

while (<>)循环中,eofeof(ARGV)可用于检测   每个文件的结尾,而eof()将检测到最后一个文件的结尾   仅限文件。

答案 1 :(得分:3)

总是 use strictuse warnings位于您的程序顶部,并使用my声明变量接近其第一个使用点。

最简单的方法是在ARGV文件句柄上测试文件结尾,以确定何时打开新文件。

此代码使用状态变量$eof来记录先前的文件是否已被完全读取,以避免在@table列表末尾不必要地向@ARGV数组添加新元素到了。

use strict;
use warnings;

my @table;
my $eof = 1;

while (<>) {
  chomp;
  push @table, [] if $eof;
  push @{$table[-1]}, $_;
  $eof = eof;
}

@Alan Haggai Alavi's在文件末尾递增索引而不是设置标志的想法要好得多,因为它避免了在每个文件的开头显式创建空数组的需要。

这是我对他的解决方案的看法,但它完全取决于艾伦的帖子,他应该为此获得赞誉。

use strict;
use warnings;

my @table;
my $index = 0;

while (<>) {
  chomp;
  push @{$table[$index]}, $_;
  $index++ if eof;
}

答案 2 :(得分:2)

文件数组引用的哈希:

my %files;
while (<>) {
  push @{$files{$ARGV}}, $_;
}

答案 3 :(得分:2)

您可以利用File :: Slurp来避免自己打开和关闭文件。

use strict;
use warnings;

use File::Slurp;

my @table = ();

foreach my $arg ( @ARGV ) {
   push @table, read_file( $arg, array_ref => 1 );
}