
Ich versuche, eine Datei mit den folgenden Daten unter UNIX zu aggregieren. Ich muss die Beträge addieren, wenn der Schlüssel derselbe ist.
Key,amount,date,Time
abc-xyz-12234,45,15-08-91,23:00
pqr-vgh-5241,15,15-08-91,21:00
abc-xyz-12234,35,15-08-91,23:00
pqr-vgh-5241,24,15-08-91,21:00
abc-xyz-12234,655,15-08-91,23:00
lkj-erf-8542,281,15-08-91,10:00
pqr-vgh-5241,40,15-08-91,21:00
Die Ausgabe sollte wie folgt aussehen
abc-xyz-12234,735,15-08-91,23:00
pqr-vgh-5241,79,15-08-91,21:00
lkj-erf-8542,281,15-08-91,10:00
Ich habe es mit dem folgenden Befehl versucht, aber es gibt mir nur uniq
cat file | grep "abc-xyz-12234" | uniq
Antwort1
Eine weitere mögliche Lösung awk
könnte sein:
awk 'BEGIN { FS = OFS = "," }
NR != 1 { y[$1] += $2; $2 = y[$1]; x[$1] = $0; }
END { for (i in x) { print x[i]; } }' file
Der Fehler besteht darin, dass Ihre Bestellung nicht erhalten bleibt. Das Ergebnis könnte also sein:
pqr-vgh-5241,79,15-08-91,21:00
abc-xyz-12234,735,15-08-91,23:00
lkj-erf-8542,281,15-08-91,10:00
Antwort2
Dies können Sie mit awk tun:
#!/bin/sh
sort | awk -F, '
function result() {
if ( key != "" ) {
printf "%s,%d,%s\n", key, value, datetime;
}
}
BEGIN { key = ""; value = 0; datetime = ""; }
$2 ~ /^[0-9]+/ {
if ( $1 == key ) {
value += $2;
} else {
result();
key = $1;
value = $2;
datetime = $3 "," $4;
}
}
END { result(); }
'
Geben
./foo <input
abc-xyz-12234,735,15-08-91,23:00
lkj-erf-8542,281,15-08-91,10:00
pqr-vgh-5241,79,15-08-91,21:00
Antwort3
Hier ist eine Möglichkeit in Perl. Nennen Sie es so ./script file.ext
:
use warnings;
use strict;
my %data;
my @order;
while (<>){
next if $. == 1;
my @line = split /,/;
if (defined $data{$line[0]}){
$data{$line[0]}->[1] += $line[1];
}
else {
$data{$line[0]} = \@line;
push @order, $line[0];
}
}
for (@order){
print join(',', @{$data{$_}});
}
Antwort4
Dabei wird Miller ( mlr
) verwendet, um die Summe der amount
Felder für alle Datensätze zu berechnen, die nach den Feldern Key
, date
, und gruppiert sind Time
. Miller fügt die Summe als neues Feld , amount_sum
am Ende der Liste der Felder hinzu, daher ordnen wir die Felder auch neu an und benennen sie neu.
mlr --csv \
stats1 -a sum -f amount -g Key,date,Time then \
reorder -f Key,amount_sum then \
label Key,amount file
Ausgabe unter Berücksichtigung der Daten in der Frage:
Key,amount,date,Time
abc-xyz-12234,735,15-08-91,23:00
pqr-vgh-5241,79,15-08-91,21:00
lkj-erf-8542,281,15-08-91,10:00
Wenn Sie den Header nicht in der Ausgabe haben möchten, verwenden Sie ihn mlr
mit der entsprechenden --headerless-csv-output
Option.