Contagem de ocorrências de texto por linha

5

Eu tenho que analisar grandes arquivos de texto onde certas linhas são de interesse e outras não. Dentro daqueles de interesse eu tenho que contar as ocorrências de uma certa palavra-chave.

Assumindo que o arquivo é chamado input.txt e se parece com isso:

format300,format250,format300
format250,ignore,format160,format300,format300
format250,format250,format300

Eu quero excluir as linhas com ignore e contar o número de format300 , como faço isso?

O que eu tenho até agora é este comando que só conta ONCE POR LINHA (que ainda não é bom o suficiente):

cat input.txt | grep -v ignore | grep 'format300' | wc -l

Alguma sugestão? Se possível, quero evitar o uso do perl.

    
por basZero 08.04.2016 / 16:20

4 respostas

7

Você não precisa do primeiro cat , que é conhecido como Uso inútil de gato (UUOC) .

Além disso, muito útil é grep -o , que apenas exibe os padrões correspondentes, um por linha.

E, em seguida, conte as linhas com wc -l .

grep -v ignore YOUR_FILE | grep -o format300 | wc -l

Isso imprime 3 para sua pequena amostra.

    
por 08.04.2016 / 18:39
9

Este one-liner deve ser capaz de fazer o que quiser:

grep -v ignore input.txt | sed 's/format300/format300\n/g' | grep -c "format300"

basicamente, você está substituindo cada ocorrência de sua palavra-chave pela própria palavra-chave e por um caractere de nova linha, o que efetivamente faz com que seu fluxo de entrada tenha a palavra-chave apenas uma vez em qualquer linha. Então, grep -c está contando linhas com sua palavra-chave nelas.

    
por 08.04.2016 / 16:24
3

O arquivo de entrada pode conter correspondências parciais que invalidariam o resultado, por exemplo:

1 format300,format250,format300
2 format250,ignore,format160,format300,format300
3 format250,format250,format300
4 format999,format300000,format999
5 format999,ignore_me_not,format300

Você não deseja contar format300000 na linha 4 ou ignorar a linha 5 porque ignore_me_not contém a substring ignore .

Isso faria o truque:

grep -v "\bignore\b" FILE |grep -o "\bformat300\b"|wc -l

Saída correta é

4

.. porque a linha 2 é ignorada, a linha 5 não é e a linha 4 não contém exatamente format300 .

Se você deixar a parte wc -l sair, poderá ver exatamente o que está sendo correspondido:

    
por 08.04.2016 / 19:37
2

Um caminho Perl:

perl -lne '$k+=(s/format300//g) unless /ignore/; }{ print $k' input.txt 

O s/format300//g substituirá todas as ocorrências de format300 por nada e retornará o número de substituições. É uma maneira simples de contar as ocorrências. O número é então adicionado a $k e a coisa toda só acontece se a linha não corresponder a ignore . A abreviação }{ é perl para "faça isso depois que você terminar de ler o arquivo, então print $k imprimirá o número total encontrado.

    
por 08.04.2016 / 16:54