Dodawanie liczb z wyniku grep

23

Uruchomię następujące polecenie:

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

i otrzymuję następujący wynik:

1
4
0
8

Chciałbym dodać każdą z liczb do zmiennej zmiennej zliczającej. Czy istnieje magiczny liniowiec, który ktoś może mi pomóc zbudować?

Amir Afghani
źródło

Odpowiedzi:

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

To nie drukuje listy, ale drukuje sumę. Jeśli chcesz zarówno listę, jak i sumę, możesz:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
Shawn J. Goff
źródło
Shawn - dziękuję za odpowiedź. Jak mogę wrócić do skryptu bash z awk?
Amir Afghani,
2
@Amir Użyłbyś pierwszego takiego: variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')To wstawia wynik polecenia (który jest tylko wartością sumaryczną) do zmiennej o nazwievariable
Shawn J. Goff
3
@Amir Afghani Również możesz chcieć zmienić grep na "[0-9]\+ errors". Będzie to pasować, jeśli masz raportowanie liniowe> 9 błędów.
Shawn J. Goff,
Tak, wow, nie mogę uwierzyć, że to przegapiłem. Dziękuję Ci.
Amir Afghani,
Shawn, wynik wydaje się, że nie sumuje moich wyników. Wygląda to tak: Błędy ogółem = + 259 + 7581 + 8852 + 2014 + 3189 ++ 13572 + 11438 +++ 6 + 4172 +
Amir Afghani
8

Wszystko to można również zrobić w awk:

awk '"[0-9]+ errors" {sum += $1}; END {print sum}' verification_report_3.txt
Trey Hunner
źródło
6

Wygląda na to, że używasz systemu GNU , więc jeśli dostępna jest obsługa wyrażeń regularnych Perla , możesz napisać coś takiego:

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

PS Zmodyfikowałem wyrażenie regularne (dodałem + kwantyfikator), aby pozwolić na liczby> 9.

PS Alternatywnie wystarczy awk (przy założeniu GNU awk ):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile
Dimitre Radoulov
źródło
pierwszy dla mnie drukuje to, co już poszło do fajki ...
Xerus
3

Spróbuj przesłać dane wyjściowe z grep do

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

źródło
2

Używam tego:

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

Nie jest skuteczny w przypadku dużych list, ale w większości moich przypadków użycia jest w porządku. Zwykle używam funkcji powłoki do automatyzacji procesu, tak że muszę tylko podać nazwę pliku:

## 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; }

Zawsze możesz zastąpić znacznik końca wiersza określonym separatorem elementów lub klasą znaków, jeśli dane są rozdzielane w inny sposób.

dęby
źródło