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?

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 - 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

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

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}'

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.