Ajouter des nombres à partir du résultat d'un grep

23

J'exécute la commande suivante:

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

et j'obtiens le résultat suivant:

1
4
0
8

Je voudrais ajouter chacun des nombres à une variable de comptage en cours. Y a-t-il une doublure magique que quelqu'un peut m'aider à construire?

Amir Afghani
la source

Réponses:

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

Cela n'imprime pas la liste mais imprime la somme. Si vous voulez à la fois la liste et la somme, vous pouvez faire:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
Shawn J. Goff
la source
Shawn - merci pour votre réponse. Comment puis-je retourner le total au script bash depuis awk?
Amir Afghani
2
@Amir Vous utiliseriez le premier comme celui-ci variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')Cela place la sortie de la commande (qui n'est que la valeur de somme) dans la variable appeléevariable
Shawn J. Goff
3
@Amir Afghani Aussi, vous voudrez peut-être changer votre grep en "[0-9]\+ errors". Cela correspondra si vous avez une ligne signalant> 9 erreurs.
Shawn J. Goff
Ouais, wow, je ne peux pas croire que j'ai raté ça. Merci.
Amir Afghani
Shawn, la sortie semble ne pas additionner mes résultats. Il ressemble à ceci: Total des erreurs = + 259 + 7581 + 8852 + 2014 + 3189 ++ 13572 + 11438 +++ 6 + 4172 +
Amir Afghani
8

Cela peut également être fait en awk:

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

Vous semblez utiliser le système GNU , donc si le support des expressions régulières Perl est disponible, vous pouvez écrire quelque chose comme ceci:

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

PS J'ai modifié l'expression régulière (ajouté le quantificateur +) pour permettre des nombres> 9.

PS Alternativement, awk est suffisant (en supposant awk GNU ):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile
Dimitre Radoulov
la source
le premier pour moi imprime juste ce qui est déjà entré dans la pipe ...
Xerus
3

Essayez de canaliser la sortie de votre grep vers

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

la source
2

J'utilise ceci:

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

Ce n'est pas efficace pour les grandes listes, mais pour la plupart de mes cas d'utilisation, c'est bien. J'utilise généralement une fonction shell pour automatiser le processus afin que je n'aie qu'à fournir un nom de fichier:

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

Vous pouvez toujours remplacer le marqueur de fin de ligne par un séparateur d'éléments ou une classe de caractères spécifique si vos données sont délimitées d'une autre manière.

deaks
la source