如何根据Perl中的先前读取行执行操作?

时间:2009-08-10 07:34:23

标签: perl

我仍然在学习Perl脚本,并且在完成以下任务时需要帮助。

Sample data:


INV ,GOOD"
2405
INV ,BAD"
42
LOAD ,GOOD"
35588
LOAD ,BAD"
675
TRNS ,GOOD"
6
TRNS ,BAD"
122

我想在GOOD和BAD下添加值。

GOOD, <sum of all good values>
BAD, <sum of all bad values>

任何人都可以建议我读取第一行的代码并将下一行的值放在数组中以便将它们添加到后面。

4 个答案:

答案 0 :(得分:7)

可能是这样的:

while (<>)
{
  $good += <> if (m/GOOD/);
  $bad += <> if (m/BAD/)
}

print "GOOD: $good";
print "BAD: $bad";

这只是将值与您的值相加并打印出来,而不是将它们累积在一个数组中。虽然改变它来存储中间值并不是太难。

答案 1 :(得分:4)

#!/usr/bin/perl

use strict;
use warnings;

my $bad = 0;
my $good = 0;
while (<>) {
    if ( /,GOOD"$/ ... /^(\d+)$/ ) {
        $good += $1 if defined($1);
    }
    if ( /,BAD"$/ ... /^(\d+)$/ ) {
        $bad += $1 if defined($1);
    }
}

print "GOOD, $good\n";
print "BAD, $bad\n";

在man perlop(Range Operator)中解释了在标量上下文中使用范围运算符,它非常酷。得到了Perl Cookbook的答案,食谱6.8。

答案 2 :(得分:2)

 use strict;                                     
 use warnings;                                   

 use Data::Dumper;                               

 my %to_sum;                                     
 while (<DATA>) {                                
     /,(GOOD|BAD)"$/;
     next unless $1;                            
     push @{ $to_sum{$1} ||= [] }, scalar <DATA>;
 }                                               
 chomp @$_ for values %to_sum;                   
 print Dumper \%to_sum;                          

 __DATA__                                        
 INV ,GOOD"                                      
 2405                                            
 INV ,BAD"                                       
 42                                              
 LOAD ,GOOD"                                     
 35588                                           
 LOAD ,BAD"                                      
 675                                             
 PIN ,GOOD"                                      
 6                                               
 TRNS ,BAD"                                      
 122                                             

给你

 $VAR1 = {                     
           'BAD' => [          
                      '42',    
                      '675',   
                      '122'    
                    ],         
           'GOOD' => [         
                       '2405', 
                       '35588',
                       '6'     
                     ]         
         };                    

答案 3 :(得分:-2)

以下将数字放在数组中。解析将容忍空行或其他输入,它将等待GOOD或BAD,然后使用下一行中的数字。

#!/usr/bin/perl -w
use strict;
use warnings;

my $state = 0;
my $state_good = 1;
my $state_bad  = 2;
my @goods = ();
my @bads = ();


while (my $line = <>) {
        chomp($line);

        if ($line =~ /GOOD/) {
                $state = $state_good;
                next;
        }
        if ($line =~ /BAD/) {
                $state = $state_bad;
                next;
        }
        next if $state == 0;

        if ($state == $state_good) {
                push @goods, $line;
                $state = 0;
        }
        if ($state == $state_bad) {
                push @bads, $line;
                $state = 0;
        }
}


print "sum good: ", sum(@goods), "\n";
print "sum bad:  ", sum(@bads),  "\n";

sub sum {
        my $ret = 0;
        while (@_) {
                my $n = shift;
                $ret += $n;
        }
        return $ret;
}