【问题标题】:Working through multiple files one at a time in perl?在perl中一次处理多个文件?
【发布时间】:2013-04-10 21:28:07
【问题描述】:

我有一个 perl 脚本,它打开一个 txt 文件,对其进行解析,以便将适当的文本输出到 csv 文件。我现在为一个文件工作得很好,但是我有很多类似的文件要以完全相同的方式处理。我希望能够自动执行此操作,因此代码将通过 file1.txt 工作并解析我想要 output.csv 的文本,然后通过 file2.txt 工作并将此输出附加到相同的 output.csv。我在下面包含了我的代码的相关位,仅排除了在 while 循环中进行实际解析的代码,因为我不需要更改它。输入文件的名称一致,例如file1.txt、file2.txt、file3.txt 等都在同一个目录中

my $mode = "none";
open(my $infile,"<","file1.txt") or die $!;
open (my $outfile,">>","output.csv") or die $!;
while (<$infile>)
{
    chomp; 
    if ($_ =~ /^Section 1/) {
        $mode = "sec1";
    }
    if ($_ =~ /^Section 2/) {
        $mode = "sec2";
    }

    if ($mode =~ "sec1") {
      $_=~ tr/,//d;

      if ($_ =~ /.\%$/){
        print $outfile $_;
        print $outfile "\n";
      }
      else{
        print $outfile $_;  
      }

    }    
}

close $infile;
close $outfile;

输出文件应该类似于这个(显然不是这个文本,我只是强调它必须附加输出,我想我已经使用 >> 而不是 >)

this is from file 1
this is from file 2
this is from file 3

【问题讨论】:

    标签: perl parsing


    【解决方案1】:

    你只需要像这样将它包装在一个循环中:

    for my $file ( @list_files ) {
        open $in_fh, "<", $file;
        while (my $line = <$in_fh>) {
        # and the rest of your stuff goes here
    

    【讨论】:

      【解决方案2】:

      您可以使用 菱形运算符 &lt;&gt; 和标量 $ARGV 变量:

      use strict; use warnings;
      
      while (<>) {
          print "Processing [$_] from $ARGV\n";
      }
      

      这是一样的

      use strict; use warnings;
      
      while (<ARGV>) {
          print "Processing [$_] from $ARGV\n";
      }
      

      如果@ARGV 中有东西。

      【讨论】:

      • 你是对的! 似乎与 相同。后面话有点多……谢谢!
      • @TrueY: &lt;&gt;&lt;ARGV&gt; 相同,而@ARGV 中有东西,当@ARGV 为空时与&lt;STDIN&gt; 相同。
      • @Borodin:是的。如果@ARGV 为空,&lt;ARGV&gt; 的行为相同。
      • @TrueY:我以为ARGV 是不同的,并没有默认为STDIN。可惜没有办法做到这一点。
      【解决方案3】:

      只需将必要的文件放入@ARGV,就好像它们是在命令行上键入的一样。然后从ARGV 文件句柄中读取。

      use strict;
      use warnings;
      
      our @ARGV = do {
          opendir my $dh, '.' or die $!;
          grep /^file\d+\.txt$/, readdir $dh;
      };
      
      while ( <ARGV> ) {
        ...
      }
      

      【讨论】:

      • @ARGV = glob("file*.txt"); 呢?
      • @TrueY:我选择了grep / readdir,以防需要更好的过滤。 file\d+\.txtfile.+\.txt 之间有很多区别
      • 你对!我的意思是使用 glob 而不是 open、readdir、closedir 组合。如果你真的需要严格的规则,那么你可以使用@ARGV = grep /^file\d+\.txt$/ glob("file*.txt");
      • @TrueY:是的,我明白你的意思。我想说的是您的glob 相当于查找与正则表达式file.+\.txt 匹配的文件名。加上grep,我认为你的替代方案比简单的opendir/readdir/grep 要笨拙得多,所以我坚持原来的解决方案。
      • @Wolf:哇,这是一个旧的!是的,当我的意思是opendir 时,我写了open,仅此而已。我已经整理了我的代码;它现在应该适合你。感谢您指出这一点。请注意,glob 会在 file 和点之间找到带有 anything 的文件,而正则表达式会坚持那里有十进制数字。
      【解决方案4】:

      在命令行中打开所有文件很容易。有一个特殊的文件句柄,称为ARGV

      例子:

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      while (<ARGV>) {
          print $_;
      }
      

      命令行:

      test.pl file*.txt
      

      所有文件都将被连接起来。

      如果代码“内部”有文件列表,则可以将它们加载到 @ARGV 数组中,然后使用 &lt;ARGV&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-05
        • 2011-06-02
        • 2022-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-24
        • 1970-01-01
        相关资源
        最近更新 更多