Как я могу выполнить операцию, основанную на предыдущей строке чтения в Perl? - PullRequest
1 голос
/ 10 августа 2009

Я все еще изучаю скрипты на Perl, и мне нужна помощь в выполнении задачи ниже.

Sample data:


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

Я хочу добавить значения в разделе ХОРОШО и ПЛОХО.

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

Может кто-нибудь предложить мне код для чтения первой строки и поместить значения из следующей строки в массив, чтобы добавить их в последнюю.

Ответы [ 4 ]

7 голосов
/ 10 августа 2009

Это может быть что-то вроде этого:

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

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

Это просто суммирует значения по мере их продвижения и распечатывает их, а не накапливает их в массиве. Однако было бы не сложно изменить его для хранения промежуточных значений.

4 голосов
/ 10 августа 2009
#!/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 (Оператор диапазона), и это довольно круто. Получил ответ из Perl Cookbook, рецепт 6.8.

2 голосов
/ 10 августа 2009
 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'     
                     ]         
         };                    
0 голосов
/ 10 августа 2009

Следующее помещает числа в массивы. Разбор будет терпимым для пустых строк или другого ввода, он будет ждать ХОРОШЕГО или ПЛОХОГО, а затем будет использовать число из следующей строки.

#!/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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...