Wie würden Sie die Ausgabe jeder Zeile von awk addieren?
Zum Beispiel
cat foo | awk '{print $1}
42
42
42
Ich suche die Antwort auf 42+42+42 (126).
Ich versuche, eine For-Schleife zu schreiben, um dies zu tun, aber es muss einen einfacheren Weg geben
#Not Working, and way too complex
cat foo |awk '{ print $1 }'|for i in $1 do; foo=$(( foo+$(i) )) done| echo $foo
Ich könnte eine Weiterleitung an durchführen wc -l
, aber das druckt nur die Anzahl der Zeilen aus, wertet sie nicht aus.
Wie kann ich jede Zeile von awk auswerten?
Antwort1
Eine grundsätzliche Vorgehensweise anhand Ihres Beispiels:
awk '{sum+=$1} END {print sum}' file
Antwort2
Wenn Sie Kontrolle über das awk-Programm haben, führen Sie die Addition innerhalb von awk durch, wie @jasonwryan zeigt.
Wenn Sie die von awk ausgegebenen Zahlen wirklich summieren möchten, leiten Sie die Ausgabe in eines der folgenden Elemente um:
| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }
Im zweiten Beispiel befindet sich der Echo-Befehl innerhalb der Klammern, da Bash die Pipeline in einer Untershell ausführt und daher keine Änderungen an der Variable „$sum“ vorhanden sind, wenn die Untershell beendet wird.
Antwort3
Bash kann nicht mit Dezimalzahlen umgehen, aber es kann einfache Manipulationen von Ganzzahlen verarbeiten, Sie müssen nur einen Trick anwenden wieProzesssubstitutionum die Variable außerhalb der Schleife zugänglich zu machen:
n=0;while read i; do let n+=$i; done < <(awk '{print $1}' foo); echo $n;
oder
n=0;while read i; do n=$((n+i)); done < <(awk '{print $1}' foo); echo $n;
Dies n=0
dient nur dazu, sicherzustellen, dass es $n
immer 0 ist. Andernfalls würde das zweite Ausführen dieser Befehle 252 statt 126 zurückgeben.
Der direkteste Weg wäre zwar, gawk
für die Berechnung zu verwenden, Sie können jedoch auch einen Perl-Einzeiler verwenden:
awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'
Das -l
Flag entfernt Zeilenumbrüche ( chomp
) und fügt am Ende jeder gedruckten Zeichenfolge einen hinzu. Das -n
bedeutet, die Datei zeilenweise zu lesen, jede Zeile als zu speichern $_
und das mit bereitgestellte Skript auszuführen -e
.
Oder machen Sie das Ganze in Perl:
perl -alne '$k+=$F[0];END{print "$k"};' foo
Das -a
Flag für Perl aktiviert die automatische Zeilenaufteilung (wie gawk
). Standardmäßig werden Felder an Leerzeichen aufgeteilt, aber das kann mit geändert werden -F
. Die resultierenden Felder werden als Array gespeichert, @F
sodass das erste Feld ist $F[0]
.
Antwort4
Die Einzeilermethode, die ich normalerweise für einfache Summen wie diese verwende, besteht darin, eine Pipe an xargs zu senden, um die gesamte Ausgabe von awk in einer Zeile zu erhalten, dann durch sed, um Leerzeichen in Pluszeichen umzuwandeln, und schließlich in bc, um die Berechnung durchzuführen:
cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc