AWK, Summe der Kategorie

AWK, Summe der Kategorie

Ich habe jede Menge CSV-Dateien mit ähnlichem Inhalt. Die Werte sind normalerweise durch Kommas getrennt und sehen so aus.

product_a,  domestic,   500
product_a,  abroad,     15
product_b,  domestic,   313
product_b,  abroad,     35
product_c,  domestic,   411
product_c,  abroad,     84
product_d,  domestic,   25
product_d,  abroad,     2
...

Was ich mit AWK erreichen möchte (weil ich glaube, dass SED nicht das richtige Werkzeug für solche Operationen ist, aber ich bin ein relativ neuer Linux-Benutzer ...), ist die Summe aller Produkte (Spalte 1), eingefügt als Spalte Nr. 2. Ich kann so etwas machen

awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename

um diese Werte (Summen) zu erhalten

product_a,  515
product_b,  348
product_c,  495
product_d,  27
...

aber ich habe immer noch keine Idee, wie ich sie als zweite Spalte in die Originaldatei einfügen kann, und zwar in etwa dieser Form:

product_a,  515, domestic,  500
product_a,  515, abroad,    15
product_b,  348, domestic,  313
product_b,  348, abroad,    35
product_c,  495, domestic,  411
product_c,  495, abroad,    84
product_d,  27,  domestic,  25
product_d,  27,  abroad,    2
...

Ich habe in letzter Zeit ein bisschen sed und awk verwendet, aber bei meinen Versuchen erhalte ich normalerweise einen Fehler (z. B.: Versuch, einen Skalarwert als Array zu verwenden).

Die Zeilenreihenfolge ist nicht mein Anliegen, aber ich gehe davon aus, dass ich die Antwort als Batchdateibefehl verwenden kann.

$ for f in *.csv; do
  That Shiny Enigmatic Command > tmp && mv tmp $f
  done

BEARBEITEN
Danke an @KM. Ich bin an den Punkt gekommen, an dem ich in 3 Schritten tun kann, was ich will.

1. Schritt:

$ for f in *.csv; do 
awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' $f | sort > sum$f
done

2. Schritt:

$ for f in [^sum]*.csv; do 
join -t ',' $f sum$f | awk -F, '{print $1"," $4"," $2"," $3}' > tmp && mv tmp $f; 
done

Um es schließlich einfach auszuführen rm sum*.*. Gibt es eine Möglichkeit, es als einen Befehl vom Terminal aus auszuführen? Oder außerhalb davon?

Antwort1

Speichern Sie die Summe in einer Datei namens sum, sortiert

awk -F, '{a[$1]+=$3;}END{for (i in a)print i", "a[i];}' filename | sort > sum

cat sum 
product_a, 515
product_b, 348
product_c, 495
product_d, 27

Verbinden Sie die beiden Dateien, die erste Spalte der ersten Datei mit der ersten Spalte der zweiten (denken Sie an „Schlüssel“). Leiten Sie sie weiter awkund drucken Sie die neu angeordneten Spalten aus. Verwenden Sie dabei ( ) ,als Feldtrennzeichen.-FUndals Ausgabefeldtrennzeichen ( -OFS)

join -t ','  -1 1 -2 1 filename sum | awk -F, -OFS=, {'print $1,$4,$2,$3}'

product_a,  515,  domestic,  500
product_a,  515,  abroad,    15
product_b,  348,  domestic,  313
product_b,  348,  abroad,    35
product_c,  495,  domestic,  411
product_c,  495,  abroad,    84
product_d,  27,   domestic,  25
product_d,  27,   abroad,    2

verwandte Informationen