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.