So fügen Sie jede Ausgabe von awk hinzu

So fügen Sie jede Ausgabe von awk hinzu

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=0dient nur dazu, sicherzustellen, dass es $nimmer 0 ist. Andernfalls würde das zweite Ausführen dieser Befehle 252 statt 126 zurückgeben.


Der direkteste Weg wäre zwar, gawkfü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 -lFlag entfernt Zeilenumbrüche ( chomp) und fügt am Ende jeder gedruckten Zeichenfolge einen hinzu. Das -nbedeutet, 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 -aFlag 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, @Fsodass 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

verwandte Informationen