Perl - суммировать данные в файле - PullRequest
4 голосов
/ 01 декабря 2010

Каков наилучший способ суммировать данные из файла, который содержит около 2 миллионов записей в Perl?

Например, для такого файла:

ABC | XYZ | DEF | EGH |100

ABC | XYZ | DEF | FGH | 200

SDF | GHT | WWW | RTY | 1000

SDF | GHT | WWW | TYU | 2000

Необходимо суммировать по первым трем столбцам, например:

ABC | XYZ | DEF | 300

SDF | GHT | WWW | 3000

Крис

Ответы [ 5 ]

3 голосов
/ 01 декабря 2010

Предполагая, что всегда есть пять столбцов, пятый из которых числовой, и вы всегда хотите, чтобы первые три столбца были ключом ...

use warnings;
use strict;

my %totals_hash;

while (<>)
{
  chomp;
  my @cols = split /\|/;

  my $key = join '|', @cols[0..2];

  $totals_hash{$key} += $cols[4];
}

foreach (sort keys %totals_hash)
{
  print $_, '|', $totals_hash{$_}, "\n";
}
2 голосов
/ 01 декабря 2010

Вы можете использовать хеш как:

my %hash;
while (<DATA>) {
        chomp;
        my @tmp = split/\|/;     # split each line on |
        my $value = pop @tmp;    # last ele is the value
        pop @tmp;                # pop unwanted entry
        my $key = join '|',@tmp; # join the remaining ele to form key

        $hash{$key} += $value;   # add value for this key
}

# print hash key-values.
for(sort keys %hash) {
        print $_ . '|'.$hash{$_}."\n";
}

Идеальная ссылка

0 голосов
/ 02 декабря 2010

1-2-3-4 Я объявляю ВОЙНА КОД-ГОЛЬФА !!! (Хорошо, разумно читаемая код-игра в гольф).1006 *

0 голосов
/ 01 декабря 2010

Сортировать, чтобы поместить все записи с одинаковыми первыми 3-мя тройками рядом друг с другом. Выполните итерацию и выведите промежуточный итог, когда появится другой набор триплетов.

$prevKey="";
$subtotal=0;
open(INPUTFILE, "<$inFile");
@lines=<INPUTFILE>;
close (INPUTFILE);
open(OUTFILE, ">$outFile");
@sorted=sort(@lines);
foreach $line(@lines){
    @parts=split(/\|/g, $line);
    $value=pop(@parts);
    $value-=0; #coerce string to a number
    $key=$parts[0]."|".$parts[1]."|".$parts[2];
    if($key ne $prevKey){
        print OUTFILE "$prevKey|$subtotal\n";
        $prevKey=$key;
        $subtotal=0;
        }
    $subtotal+=$value;
    }
close(OUTFILE);

Если сортировать 2 миллиона дросселей в вашем ящике, вам, возможно, придется поместить каждую запись в файл, основанный на группе, а затем выполнить промежуточный итог для каждого файла.

0 голосов
/ 01 декабря 2010

Предполагается, что ваш входной файл содержит записи в отдельных строках.

perl -n -e 'chomp;@a=split/\|/;$h{join"|",splice@a,0,3}+=pop@a;END{print map{"$_: $h{$_}\n"}keys%h}' < inputfile
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...