Estou procurando um comando para contar o número de todas as palavras em um arquivo. Por exemplo, se um arquivo é assim,
today is a
good day
então deve ser impresso 5
, pois há 5
palavras lá.
Estou procurando um comando para contar o número de todas as palavras em um arquivo. Por exemplo, se um arquivo é assim,
today is a
good day
então deve ser impresso 5
, pois há 5
palavras lá.
Respostas:
O comando wc
aka. a contagem de palavras pode fazer isso:
$ wc -w <file>
$ cat sample.txt
today is a
good day
$ wc -w sample.txt
5 sample.txt
# just the number (thanks to Stephane Chazelas' comment)
$ wc -w < sample.txt
5
wc -w
não têm a mesma definição que para o GNU grep -w
. Para wc
uma palavra, é uma sequência de um ou mais caracteres não espaciais ( [:space:]
classe de caractere no código do idioma atual). Por exemplo, foo,bar
e foo bar
(com um espaço sem quebra) são cada uma palavra.
Eu vim com isso apenas para o número:
wc -w [file] | cut -d' ' -f1
5
Eu também gosto da wc -w < [file]
abordagem
Por fim, para armazenar apenas a contagem de palavras em uma variável, você pode usar o seguinte:
myVar=($(wc -w /path/to/file))
Isso permite que você pule o nome do arquivo com elegância.
wc -w < "$file"
para APENAS o número.
A melhor solução é usar o Perl:
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@Bernhard
Você pode verificar o código fonte de wc
comando do coreutils, eu testei na minha máquina, com o arquivo subst.c
no bash 4.2 source.
time wc -w subst.c
real 0m0.025s
user 0m0.016s
sys 0m0.000s
E
time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c
real 0m0.021s
user 0m0.016s
sys 0m0.004s
Quanto maior o arquivo, mais eficiente o Perl é em relação a wc
.
wc
levei ~ 14seg enquanto Perl levou ~ 5seg!
split
on /\s+/
é como um, split(' ')
exceto que qualquer espaço em branco à esquerda produz um primeiro campo nulo. Essa diferença fornecerá uma palavra extra (o primeiro campo nulo, ou seja) por link de linha . Portanto, use o (split(" ", $_))
contrário para um arquivo criado assim: echo -e "unix\n linux" > testfile
sua linha de base reporta três palavras.
wc
será significativamente mais rápido, assim como com PERLIO=:utf8
, perl
será significativamente mais lento.
$ function wordfrequency() { awk 'BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) { word = tolower($i) words[word]++ } } END { for (w in words) printf("%3d %s\n", words[w], w) } ' | sort -rn }
$ cat your_file.txt | wordfrequency
Isso lista a frequência de cada palavra que ocorre no arquivo fornecido. Eu sei que não é o que você pediu, mas é melhor! Se você quiser ver as ocorrências da sua palavra, basta fazer o seguinte:
$ cat your_file.txt | wordfrequency | grep yourword
Eu até adicionei essa função aos meus arquivos .dotfiles
Fonte: Ruby da ala AWK
O wc
programa conta "palavras", mas essas não são, por exemplo, as "palavras" que muitas pessoas verão quando examinam um arquivo. O vi
programa, por exemplo, usa uma medida diferente de "palavras", delimitando-as com base em suas classes de caracteres, enquanto wc
simplesmente conta as coisas separadas por espaços em branco . As duas medidas podem ser radicalmente diferentes. Considere este exemplo:
first,second
vi
vê três palavras ( primeira e segunda , bem como a vírgula que as separa), enquanto wc
vê uma (não há espaço em branco nessa linha). Existem muitas maneiras de contar palavras, algumas são menos úteis que outras.
Embora o Perl seja mais adequado para escrever um contador para as palavras do estilo vi, aqui está um exemplo rápido de using sed
, tr
e wc
(moderadamente portátil usando retornos de carro literais ^M
):
#!/bin/sh
in_words="[[:alnum:]_]"
in_punct="[][{}\\|:\"';<>,./?\`~!@#$%^&*()+=-]"
sed -e "s/\($in_words\)\($in_punct\)/\1^M\2/g" \
-e "s/\($in_punct\)\($in_words\)/\1^M\2/g" \
-e "s/[[:space:]]/^M/g" \
"$@" |
tr '\r' '\n' |
sed -e '/^$/d' |
wc -l
Comparando contagens:
wc
dá 28.Para referência, o POSIX vi diz:
No código do idioma POSIX, o vi deve reconhecer cinco tipos de palavras:
Uma sequência máxima de letras, dígitos e sublinhados, delimitada nas duas extremidades por:
Caracteres que não sejam letras, dígitos ou sublinhados
O início ou o fim de uma linha
O início ou o fim do buffer de edição
Uma sequência máxima de caracteres que não sejam letras, dígitos, sublinhados ou caracteres, delimitada nas duas extremidades por:
- Uma letra, dígito, sublinhado
<blank>
personagens- O início ou o fim de uma linha
- O início ou o fim do buffer de edição
Uma ou mais linhas em branco seqüenciais
O primeiro caractere no buffer de edição
O último que não está
<newline>
no buffer de edição
wc -w $FILE
?