O comando wc -w gera uma resposta incorreta [duplicada]

2

Eu tenho que descobrir quantas vezes a palavra shell é usada em um arquivo. Eu usei grep "shell" test.txt | wc -w para contar quantas vezes essa palavra foi usada, mas o resultado é 4 em vez de 3. O conteúdo do arquivo é:

this is a test file
for shell_A
shell_B
sh
shel
and 
shell_C
script project
    
por J.Doe 06.02.2016 / 17:14

4 respostas

18

O comando wc está contando as palavras na saída do grep, que inclui "for":

> grep shell test.txt
for shell_A
shell_B
shell_C

Então, existem 4 palavras.

Se você quiser apenas contar o número de linhas que contêm uma palavra específica em um arquivo, use a opção -c do grep, por exemplo,

grep -c shell test.txt

Nenhum deles realmente conta palavras , mas pode combinar outras coisas que incluem string . A maioria das implementações de grep (GNU grep, BSDs modernos, bem como AIX, HPUX, Solaris) fornece uma opção -w para palavras, mas isso não está em POSIX. Eles também reconhecem uma expressão regular, por exemplo,

grep -e '\<shell\>' test.txt

que corresponde à opção -w . Novamente, isso não está em POSIX. O Solaris documento , enquanto o AIX e o HPUX descrevem -w sem mencionar a expressão regular. Todos parecem ser consistentes, tratando uma "palavra" como uma sequência de alfanuméricos mais sublinhado.

Você poderia usar uma expressão regular POSIX com grep para combinar palavras (separadas por espaços em branco, etc), mas seu exemplo não possui nenhuma que seja apenas "shell": todas elas possuem algum outro caractere tocando as correspondências. Alternativamente, se você se importa apenas com alfanuméricos (e não sublinhado) e não se importa com substrings correspondentes, você poderia fazer

tr -c '[[:alnum:]]' '\n' test.txt |grep -c shell

A opção -o sugerida é não-POSIX, e como o OP não limitou a questão ao Linux ou BSDs, não é o que eu recomendaria. Em ambos os casos, não corresponde a palavras , mas strings (que era a expectativa do OP).

Para referência:

por 06.02.2016 / 17:20
16

O comando 'grep' está exibindo as linhas inteiras nas quais "shell" aparece. Não apenas a palavra "shell". Como pode ser visto abaixo:

grep shell test.txt
for shell_A
shell_B
shell_C

Eu recomendaria usar a opção

-o, --only-matching

Então:

grep -o "shell" test.txt | wc -w
    
por 06.02.2016 / 17:25
5

desde que você pode ter a palavra "shell" várias vezes em uma linha eu começaria com quebrando o texto em palavras únicas por linha e depois fazer o grep

< test.txt tr -s "[[:blank:]]" "\n" | grep "shell" | wc -w

você também pode usar wc -l ou acabar com wc e usar grep -c "shell"

E você pode até remover a necessidade de tr no arquivo que você tem e usar:

grep -c "shell" test.txt

    
por 06.02.2016 / 17:28
1

Você deve usar wc -l para isso, ou seja, grep shell test.txt | wc -l . Isso retorna 3.

    
por 07.02.2016 / 09:51

Tags