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?

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

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

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

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.