Uma das coisas que eu senti falta no Linux foi um comando que pudesse fazer a contagem de palavras de um arquivo de texto no Linux. Ao pesquisar na internet, é possível encontrar alguns scripts, mas muitos deles são longos e incompreensíveis e por isso não são muito interessantes de serem usados, pelo menos no meu caso.
Por isso resolvi desenvolver meu próprio contador de palavras. Eu queria um contador de palavras que pudesse contar as palavras do texto inteiro e de forma eficiente. Como não achei nenhum comando específico para isso, então com alguns comandos, o resultado foi esse:
Foi usado o comando tr para substituir todos os espaços por uma quebra de linha, assim fica uma palavra por linha.
Foi usado o comando sed para eliminar qualquer linha em branco e caracteres de pontuação que por acaso não estejam junto às palavras.
O comando wc com o parâmetro -l contou as linhas. Os comandos anteriores posicionaram uma palavra em cada linha e eliminou as que não possuíam uma palavra, o que resulta no número total de palavras.
Obs.: não deixe o caractere "!" solto no texto para evitar erros de leitura pelo comando tr.
Coloque o nome que achar mais conveniente e faça o teste para comprovar sua eficiência em poucas linhas. Como a entrada vai ser pelo comando tr, deve-se usar o carácter de direcionamento "<", conforme visto a seguir:
./palavra < documento.txt
Para exemplificação, será usado um conjunto de palavras para a demonstração da funcionalidade:
./palavra <<< "pc linux manjaro, kde xfce , shell bash - linux, mxnt ... .txz ???"
[2] Comentário enviado por vmmello em 15/04/2021 - 12:09h
O comando wc até conta palavras com a opção -w, mas ele inclui os caracteres de pontuação como palavra.
O comando tr não tem nenhum problema com o caractere de exclamação (!). A questão é que o bash expande o caractere de exclamação para a ultima linha de comando executada, o que afeta a contagem de palavras. Talvez isso seja corrigido apenas removendo o termo $1 que parece desnecessário.
Uma forma alternativa de fazer a mesma coisa seria:
[code]
#!/bin/bash
tr -s ' ' '\n' | egrep -c -v -x '[[:punct:]]*[[:space:]]*[[:cntrl:]]*'
[/code]
[code]
$ ./conta.sh <<< "Conte cinco palavras , por favor \!\!\!"
5
[/code]
[code]
$ ./conta.sh <<< 'Conte cinco palavras , por favor !!!'
5
[/code]
[code]
$ echo 'Conte cinco palavras , por favor !!!' >/tmp/arquivo1.txt
$ ./conta.sh < /tmp/arquivo1.txt
5
[/code]
[4] Comentário enviado por maurixnovatrento em 15/04/2021 - 14:07h
[2] Comentário enviado por vmmello em 15/04/2021 - 12:09h
O comando wc até conta palavras com a opção -w, mas ele inclui os caracteres de pontuação como palavra.
O comando tr não tem nenhum problema com o caractere de exclamação (!). A questão é que o bash expande o caractere de exclamação para a ultima linha de comando executada, o que afeta a contagem de palavras. Talvez isso seja corrigido apenas removendo o termo $1 que parece desnecessário.
Uma forma alternativa de fazer a mesma coisa seria:
[code]
#!/bin/bash
tr -s ' ' '\n' | egrep -c -v -x '[[:punct:]]*[[:space:]]*[[:cntrl:]]*'
[/code]
[code]
$ ./conta.sh <<< "Conte cinco palavras , por favor \!\!\!"
5
[/code]
[code]
$ ./conta.sh <<< 'Conte cinco palavras , por favor !!!'
5
[/code]
[code]
$ echo 'Conte cinco palavras , por favor !!!' >/tmp/arquivo1.txt
$ ./conta.sh < /tmp/arquivo1.txt
5
[/code]
Valeu. Parece mais eficiente. Vou adaptar sem pipe e ver o resultado. Também descobri que o ! não incomoda dentro de arquivos de textos e em aspas simples. Só dá problema em aspas duplas e o $1 não interfere em nada o !, vou evoluir meu código para suportar vários arquivos de uma vez.
Dessa sua forma também ficou boa. Mas, ele tem o mesmo sintoma com o ! como eu descrevo acima.
[5] Comentário enviado por msoliver em 17/04/2021 - 02:20h
Para coisas simples, uso o wc,
Em tarefas mais precisas:
awk '{for(n=1;n<=NF;n++) {if($n~/[[:alpha:]]{1,}/)c++;}}END{print "Palavras: "c"\nLinhas: "NR}' arquivo
Palavras: 9823
Linhas: 2601
______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________
[6] Comentário enviado por maurixnovatrento em 17/04/2021 - 22:38h
[5] Comentário enviado por msoliver em 17/04/2021 - 02:20h
Para coisas simples, uso o wc,
Em tarefas mais precisas:
awk '{for(n=1;n<=NF;n++) {if($n~/[[:alpha:]]{1,}/)c++;}}END{print "Palavras: "c"\nLinhas: "NR}' arquivo
Palavras: 9823
Linhas: 2601
______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________
[7] Comentário enviado por maurixnovatrento em 17/04/2021 - 22:48h
[5] Comentário enviado por msoliver em 17/04/2021 - 02:20h
Para coisas simples, uso o wc,
Em tarefas mais precisas:
awk '{for(n=1;n<=NF;n++) {if($n~/[[:alpha:]]{1,}/)c++;}}END{print "Palavras: "c"\nLinhas: "NR}' arquivo
Palavras: 9823
Linhas: 2601
______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________
Fiz alguns testes de eficiência: Deu empate com ambas as soluções, porém o seu código é mais viável para um alias. Já o meu, vou transformá-lo em algo mais complexo.
No fim, vai me servir os dois. E novamente, valeu pela sugestão. Seu código foi um aprendizado a mais para mim.