¿Cómo contar el número total de palabras en un archivo?

18

Estoy buscando un comando para contar el número de todas las palabras en un archivo. Por ejemplo, si un archivo es así,

today is a 
good day

entonces debería imprimir 5, ya que hay 5palabras allí.

Ricardo
fuente
77
¿Lo has intentado wc -w $FILE?
don_crissti

Respuestas:

39

El comando wcalias. el recuento de palabras puede hacerlo:

$ wc -w <file>

ejemplo

$ 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
slm
fuente
1
Tenga en cuenta que las palabras para wc -wno tienen la misma definición que para GNU grep -w. Para wcuna palabra es una secuencia de uno o más caracteres no espaciales ( [:space:]clase de caracteres en el entorno local actual). Por ejemplo foo,bary foo bar(con un espacio sin interrupciones) son cada una de las palabras.
Stéphane Chazelas
7

Se me ocurrió esto por SOLO el número:

wc -w [file] | cut -d' ' -f1

5

También me gusta el wc -w < [file]enfoque

Finalmente, para almacenar solo el recuento de palabras en una variable, puede usar lo siguiente:

myVar=($(wc -w /path/to/file))

Esto le permite omitir el nombre de archivo con elegancia.

Michael Durrant
fuente
14
wc -w < "$file"por SOLO el número.
Stéphane Chazelas
3

La mejor solución es usar Perl:

perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename

@Bernhard

Puede verificar el código fuente del wccomando desde coreutils, lo pruebo en mi máquina, con el archivo subst.cen la fuente bash 4.2.

time wc -w subst.c

real    0m0.025s
user    0m0.016s
sys     0m0.000s

Y

time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c

real    0m0.021s
user    0m0.016s
sys     0m0.004s

Cuanto más grande es el archivo, más eficiente es Perl con respecto a wc.

Cuonglm
fuente
13
¿Por qué es esto mejor que wc?
Sparr
2
@Sparr por un lado porque, para mi gran sorpresa, parece ser mucho más rápido. ¡Lo probé en un archivo de texto con 141813504 palabras y wctardé ~ 14 segundos mientras que Perl tardó ~ 5 segundos!
terdon
3
Creo que el problema 'más grande' realmente es una respuesta que depende de Perl y nunca soy un gran admirador de dicha dependencia. Si la pregunta fuera sobre el rendimiento, eso sería otra cosa.
Michael Durrant
55
Tenga en cuenta que un spliton /\s+/es como un split(' ')excepto que cualquier espacio en blanco inicial produce un primer campo nulo. Esa diferencia le dará una palabra adicional (el primer campo nulo, es decir) por enlace de línea . Por (split(" ", $_))lo tanto, use lo contrario para un archivo creado de esta manera: echo -e "unix\n linux" > testfilesu one-liner informa 3 palabras.
don_crissti
1
Sus tiempos muestran que wc es más rápido (lo que importa son los tiempos de usuario y sistema). Con LC_ALL = C, wcserá significativamente más rápido, al igual que con PERLIO=:utf8, perlserá significativamente más lento.
Stéphane Chazelas
3

¡Usemos AWK!

$ 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

Esto enumera la frecuencia de cada palabra que aparece en el archivo proporcionado. Sé que no es lo que pediste, ¡pero es mejor! Si desea ver las ocurrencias de su palabra, simplemente puede hacer esto:

$ cat your_file.txt | wordfrequency | grep yourword

Incluso agregué esta función a mis archivos .dot


Fuente: AWK-ward Ruby

Sheharyar
fuente
Cuenta palabras, ¡así que es lo suficientemente bueno para mí! :-)
aggsol
3

El wcprograma cuenta las "palabras", pero esas no son, por ejemplo, las "palabras" que mucha gente vería cuando examinen un archivo. El viprograma, por ejemplo, usa una medida diferente de "palabras", delimitándolas en función de sus clases de caracteres, mientras que wcsimplemente cuenta las cosas separadas por espacios en blanco . Las dos medidas pueden ser radicalmente diferentes. Considere este ejemplo:

first,second

vive tres palabras ( primera y segunda , así como la coma que las separa), mientras wcve una (no hay espacios en blanco en esa línea). Hay muchas formas de contar palabras, algunas son menos útiles que otras.

Si bien Perl sería más adecuado para escribir un contador para las palabras de estilo vi, aquí hay un ejemplo rápido usando sed, try wc(moderadamente portátil usando retornos de carro literales ^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

Comparación de recuentos:

  • Ejecutar el script en sí mismo, me da 76 palabras.
  • El ejemplo en Perl de @cuonglm da 31.
  • Usando wcda 28.

Como referencia, POSIX vi dice:

En el entorno local POSIX, vi reconocerá cinco tipos de palabras:

  1. Una secuencia máxima de letras, dígitos y guiones bajos, delimitada en ambos extremos por:

    • Caracteres que no sean letras, dígitos o guiones bajos

    • El principio o el final de una línea.

    • El principio o el final del búfer de edición.

  2. Una secuencia máxima de caracteres que no sean letras, dígitos, guiones bajos o caracteres, delimitados en ambos extremos por:

    • Una letra, dígito, guión bajo
    • <blank> caracteres
    • El principio o el final de una línea.
    • El principio o el final del búfer de edición.
  3. Una o más líneas en blanco secuenciales

  4. El primer carácter en el búfer de edición

  5. El último que no está <newline>en el búfer de edición

Thomas Dickey
fuente