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


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

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.


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.


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


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.