2010-02-22 4 views
13

Ho un file di testo che è:Come posso sommare i valori nella colonna in base al valore in un'altra colonna?

ABC 50 
DEF 70 
XYZ 20 
DEF 100 
MNP 60 
ABC 30 

voglio un'uscita che riassume i valori individuali e li mostra come un risultato. Ad esempio, il totale di tutti i valori ABC nel file è (50 + 30 = 80) e DEF è (100 + 70 = 170). Quindi l'uscita dovrebbe riassumere tutti i nomi prima colonna uniche -

ABC 80 
DEF 170 
XYZ 20 
MNP 60 

Ogni aiuto sarà molto apprezzato.

Grazie

risposta

3

awk '{sums[$1] += $2} END { for (i in sums) printf("%s %s\n", i, sums[i])}' input_file | sort

se non è necessario i risultati in ordine alfabetico, basta semplicemente inserire la parte | sort.

+0

perdere il gatto. Il suo UUOC. – ghostdog74

+0

@ ghostdog74: effettivamente – ggiroux

1
my %data; 
while (<>) { 
    if (my ($key, $value) = /^(\w+) \s* (\d+)$/x) { 
     $data{$key} += $value; 
    } 
} 
printf "%s %s\n", $_, $data{$_} for keys %data; 
+0

perché non dividere su spazi bianchi anziché regex? – ghostdog74

+0

In entrambi i casi funzionerebbe. Il mio approccio è un po 'più convincente, ma anche un po' più complesso. –

10
$ awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}' file 
ABC 80 
XYZ 20 
MNP 60 
DEF 170 
5
$ perl -lane \ 
    '$sum{$F[0]} += $F[1]; 
    END { print "$_ $sum{$_}" 
      for sort grep length, keys %sum }' \ 
    input 
ABC 80 
DEF 170 
MNP 60 
XYZ 20
2
perl -lane '$_{$F[0]}+=$F[1]}print"$_ $_{$_}"for keys%_;{' file 

e un po 'meno semplice:

perl -ape '$_{$F[0]}+=$F[1]}map$\.="$_ $_{$_}\n",keys%_;{' file 
+0

3 caratteri più brevi: perl -anE '$ _ {$ F [0]} + = $ F [1]} pronuncia "$ _ $ _ {$ _}" per le chiavi% _; {' file –

+0

Lo so. Ma funziona solo in 5.010;) – codeholic