CLI AI

Contar ocorrências num log: grep -c não é a resposta

2026-08-11

grep -c ERROR app.log conta as linhas que contêm a palavra; grep -o ERROR app.log | wc -l conta quantas vezes ela de fato aparece. No mesmo arquivo isso dá 3 e 4, e a diferença é uma única linha com dois erros. Qual número você quer depende da pergunta que você queria fazer.

1. Quantas linhas contêm a palavra

clai
$ clai quantas linhas do app.log contêm ERROR→ grep -c ERROR app.log3

-c conta linhas com correspondência, não correspondências. Uma linha com dois ERROR continua contando como uma.

2. Quantas vezes a palavra aparece

clai
$ clai quantas vezes ERROR aparece no app.log→ grep -o ERROR app.log | wc -l4

3 contra 4 no mesmíssimo arquivo. O -o imprime cada correspondência em sua própria linha, e só então o wc -l conta ocorrências. A extra é justamente a linha com dois erros.

3. Ignorando maiúsculas

clai
$ clai conte as linhas com error sem diferenciar maiúsculas→ grep -ic error app.log4

O -i pegou uma quarta linha — aquela em que a palavra está em minúsculas. Num log escrito por vários serviços, a caixa das letras nunca é garantida.

4. As mensagens de erro mais frequentes

clai
$ clai mostre quais erros acontecem com mais frequência→ grep -o 'ERROR [a-z ]*' app.log | sed 's/ *$//' | sort | uniq -c | sort -rn      2 ERROR timeout connecting to db      1 ERROR retry failed      1 ERROR permission denied

Esse costuma ser o objetivo real. O -o extrai a mensagem, o sed corta os espaços finais, o uniq -c conta e o segundo sort -rn põe as frequentes no topo.

5. Distribuição por hora

clai
$ clai mostre em quais horas houve erros→ grep ERROR app.log | cut -c12-13 | sort | uniq -c      1 09      1 10      1 11

O cut -c12-13 tira a hora de um carimbo 2026-08-10 09:12:03. As posições dependem do formato do seu log — olhe uma linha e conte os caracteres antes de copiar isto.

6. Vários arquivos de uma vez

clai
$ clai conte os erros em cada arquivo de log→ grep -c ERROR *.logapp.log:3app2.log:3

Com mais de um arquivo, o grep imprime nome e contagem separados por dois-pontos. Para ranquear: grep -c ERROR *.log | sort -t: -k2 -rn.

Gotchas

  • grep -c não conta ocorrências. Verificado num arquivo: -c diz 3, -o | wc -l diz 4. Quando uma linha casa duas vezes, o -c não enxerga. Decida qual pergunta você está fazendo: "quantas linhas" ou "quantas vezes".
  • grep -o sem correspondências não imprime nada e sai com 1. Canalizado para wc -l parece um zero honesto, mas o status de saída é diferente de zero e um script com set -e morre exatamente ali.
  • As posições do cut -c estão presas ao formato do log. Assim que o logger acrescenta milissegundos ou um hostname no início da linha, o recorte por hora passa a contar os caracteres errados sem avisar. Para formatos instáveis, use campos: awk '{print $2}'.

Related questions

Como conto palavras inteiras em vez de trechos? grep -wo error — o -w exige fronteiras de palavra; sem ele, errors e errorlog entram na conta.

Como conto dentro de logs comprimidos? zgrep -c ERROR app.log.1.gz funciona como o grep sem descompactar o arquivo em disco.

Como conto valores distintos? Acrescente sort -u antes de contar: grep -o 'ERROR [a-z ]*' app.log | sort -u | wc -l dá o número de mensagens diferentes, não o total delas.

See also

O CliAI transforma "quantas vezes" e "quantas linhas" em dois comandos diferentes, e mostra qual escolheu. Instale em uma linha.