Hinzufügen von Zahlen aus dem Ergebnis eines Greps

23

Ich führe den folgenden Befehl aus:

grep -o "[0-9] errors" verification_report_3.txt | awk '{print $1}'

und ich bekomme folgendes Ergebnis:

1
4
0
8

Ich möchte jede der Zahlen zu einer laufenden Zählvariablen hinzufügen. Gibt es einen magischen One Liner, bei dessen Bau mir jemand helfen kann?

Amir Afghani
quelle

Antworten:

31
grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }'

Das druckt nicht die Liste, sondern die Summe. Wenn Sie sowohl die Liste als auch die Summe möchten, können Sie Folgendes tun:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
Shawn J. Goff
quelle
Shawn - danke für deine Antwort. Wie kehre ich total aus awk zum Bash-Skript zurück?
Amir Afghani
2
@Amir Sie würden das erste wie folgt verwenden variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')die Ausgabe des Befehls Dies stellt (die nur der Summenwert) in die Variable genanntvariable
Shawn J. Goff
3
@Amir Afghani Vielleicht möchten Sie auch Ihr Grep auf ändern "[0-9]\+ errors". Dies stimmt überein, wenn Sie eine Zeile mit mehr als 9 Fehlern haben.
Shawn J. Goff
Wow, ich kann nicht glauben, dass ich das verpasst habe. Vielen Dank.
Amir Afghani
Shawn, die Ausgabe scheint nicht meine Ergebnisse zu summieren. Es sieht so aus: Total Errors = + 259 + 7581 + 8852 + 2014 + 3189 + 13572 + 11438 + 6 + 4172 +
Amir Afghani
8

Dies kann alles auch in awk gemacht werden:

awk '"[0-9]+ errors" {sum += $1}; END {print sum}' verification_report_3.txt
Trey Hunner
quelle
6

Sie scheinen ein GNU- System zu verwenden. Wenn also Unterstützung für reguläre Ausdrücke in Perl verfügbar ist, können Sie Folgendes schreiben:

grep -Po '[0-9]+(?=\s+errors)' infile | 
  paste -sd+ | 
    bc

PS: Ich habe den regulären Ausdruck geändert (+ hinzugefügt), um Zahlen> 9 zuzulassen.

PS Alternativ ist awk ausreichend (vorausgesetzt, GNU awk ):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile
Dimitre Radoulov
quelle
der erste für mich druckt nur, was bereits in die Pipe gegangen ist ...
Xerus
3

Versuchen Sie, die Ausgabe von Ihrem grep in zu leiten

awk 'BEGIN {total=0;}{total+=$1;}END {print "Total: ",total}'

quelle
2

Ich benutze das:

$ echo $(cat file | sed 's/$/+/') 0 | bc

Es ist nicht effizient für große Listen, aber für die meisten meiner Anwendungsfälle ist es in Ordnung. Normalerweise benutze ich eine Shell-Funktion, um den Prozess zu automatisieren, sodass ich nur einen Dateinamen angeben muss:

## cheezy summation
##   call from .bashrc
##
getsum () { echo $(cat $1 | sed 's/$/+/') 0 | bc; }
gethsum () { echo $(cat $1 | sed 's/[gG]/*1000M/' | sed 's/[mM]/*1000K/' | sed 's/[kK]/*1000/' | sed 's/$/+/') 0 | bc; }
gethexsum () { echo ibase=16 $(cat $1 | sed 's/$/+/') 0 | bc; }

Sie können die Zeilenende-Markierung immer durch ein bestimmtes Elementtrennzeichen oder eine bestimmte Zeichenklasse ersetzen, wenn Ihre Daten auf andere Weise abgegrenzt sind.

taub
quelle