Adicionando números do resultado de um grep

23

Eu executo o seguinte comando:

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

e recebo o seguinte resultado:

1
4
0
8

Eu gostaria de adicionar cada um dos números até uma variável de contagem em execução. Existe um liner mágico que alguém possa me ajudar a construir?

Amir Afghani
fonte

Respostas:

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

Isso não imprime a lista, mas imprime a soma. Se você deseja a lista e a soma, pode fazer:

grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1; print $1} END { print SUM }'
Shawn J. Goff
fonte
Shawn - obrigado pela sua resposta. Como faço para retornar o total de volta ao script bash do awk?
Amir Afghani
2
@Amir Você usaria o primeiro como este variable=$(grep -o "[0-9] errors" verification_report_3.txt | awk '{ SUM += $1} END { print SUM }')Isso coloca a saída do comando (que é apenas o valor da soma) na variável chamadavariable
Shawn J. Goff
3
@Amir Afghani Além disso, você pode querer mudar seu grep para "[0-9]\+ errors". Isso corresponderá se você tiver uma linha relatando> 9 erros.
Shawn J. Goff
Sim, uau, eu não acredito que perdi isso. Obrigado.
Amir Afghani
Shawn, a saída parece que não está somando meus resultados. Parece assim: Total de erros = + 259 + 7581 + 8852 + 2014 + 3189 ++ 13572 + 11438 +++ 6 + 4172 +
Amir Afghani
8

Tudo isso também pode ser feito no awk:

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

Você parece estar usando o sistema GNU ; portanto, se o suporte a expressões regulares do Perl estiver disponível, você pode escrever algo como isto:

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

PS Modifiquei a expressão regular (adicionei o quantificador +) para permitir números> 9.

PS Como alternativa, o awk é suficiente (assumindo o GNU awk ):

awk 'END { print s }
/[0-9]+[[:space:]]+errors/ { 
  s += $1 
  }' infile
Dimitre Radoulov
fonte
o primeiro para mim apenas impressões que já entrou no tubo ...
Xerus
3

Tente canalizar a saída do seu grep para o

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

fonte
2

Eu uso isso:

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

Não é eficiente para listas grandes, mas para a maioria dos meus casos de uso, tudo bem. Normalmente, uso uma função de shell para automatizar o processo, de modo que só preciso fornecer um nome de arquivo:

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

Você sempre pode substituir o marcador de fim de linha por um separador de elemento específico ou classe de caractere se seus dados forem delimitados de outra maneira.

picos
fonte