comment compter le nombre total de mots dans un fichier?

18

Je recherche une commande pour compter le nombre de tous les mots d'un fichier. Par exemple, si un fichier est comme ça,

today is a 
good day

alors il devrait s'imprimer 5, car il y a des 5mots.

Richard
la source
7
As-tu essayé wc -w $FILE?
don_crissti

Réponses:

39

La commande wcaka. le nombre de mots peut le faire:

$ wc -w <file>

exemple

$ 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
la source
1
Notez que les mots pour wc -wn'ont pas la même définition que pour GNU grep -w. Pour wcun mot est une séquence d'un ou plusieurs caractères non-espace ( [:space:]classe de caractères dans l'environnement local actuel). Par exemple, foo,baret foo bar(avec un espace insécable) sont chacun un mot.
Stéphane Chazelas
7

Je suis venu avec cela pour JUSTE le nombre:

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

5

J'aime aussi l' wc -w < [file]approche

Enfin, pour stocker uniquement le nombre de mots dans une variable, vous pouvez utiliser ce qui suit:

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

Cela vous permet de sauter le nom de fichier avec élégance.

Michael Durrant
la source
14
wc -w < "$file"pour JUSTE le nombre.
Stéphane Chazelas
3

La meilleure solution est d'utiliser Perl:

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

@Bernhard

Vous pouvez vérifier le code source de la wccommande de coreutils, je teste dans ma machine, avec le fichier subst.cen bash 4.2 source.

time wc -w subst.c

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

Et

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

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

Plus le fichier est gros, plus Perl est efficace par rapport à wc.

cuonglm
la source
13
Pourquoi est-ce mieux que wc?
Sparr
2
@Sparr pour une chose car, à ma très grande surprise, il semble être beaucoup plus rapide. Je l'ai essayé sur un fichier texte avec 141813504 mots et j'ai wcpris ~ 14sec tandis que Perl a pris ~ 5sec!
terdon
3
Je pense que le «plus gros» problème est vraiment une réponse qui dépend de Perl et je ne suis jamais un grand fan d'une telle dépendance. Si la question portait sur la performance, ce serait autre chose.
Michael Durrant
5
Notez que un splitsur /\s+/est comme une split(' ')exception que les espaces blancs menant produit un premier champ nul. Cette différence vous donnera un mot supplémentaire (le premier champ nul, c'est-à-dire) par lien de ligne . Utilisez donc le (split(" ", $_))contraire pour un fichier créé comme ceci: echo -e "unix\n linux" > testfilevotre one-liner rapporte 3 mots.
don_crissti
1
Vos horaires montrent que wc est plus rapide (ce sont les temps utilisateur et système qui importent). Avec LC_ALL = C, wcsera beaucoup plus rapide, tout comme avec PERLIO=:utf8, perlsera beaucoup plus lent.
Stéphane Chazelas
3

Utilisons 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

Ceci répertorie la fréquence de chaque mot apparaissant dans le fichier fourni. Je sais que ce n'est pas ce que tu as demandé, mais c'est mieux! Si vous voulez voir les occurrences de votre mot, vous pouvez simplement le faire:

$ cat your_file.txt | wordfrequency | grep yourword

J'ai même ajouté cette fonction à mes fichiers .dot


Source: Rubis AWK

Sheharyar
la source
Il compte des mots, donc c'est assez bon pour moi! :-)
aggsol
3

Le wcprogramme compte des «mots», mais ce ne sont pas par exemple les «mots» que beaucoup de gens verraient lorsqu'ils examineraient un dossier. Le viprogramme utilise par exemple une mesure différente de "mots", les délimitant en fonction de leurs classes de caractères, tout wcen comptant simplement les choses séparées par des espaces . Les deux mesures peuvent être radicalement différentes. Considérez cet exemple:

first,second

vivoit trois mots ( premier et deuxième ainsi que la virgule qui les sépare), tandis que wcvoit un (il n'y a pas d'espace sur cette ligne). Il existe de nombreuses façons de compter les mots, certaines sont moins utiles que d'autres.

Alors que Perl serait mieux adapté à l'écriture d'un compteur pour les mots de style vi, voici un exemple rapide utilisant sed, tret wc(modérément portable en utilisant des retours chariot littéraux ^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

Comparaison des dénombrements:

  • L'exécution du script sur lui-même me donne 76 mots.
  • L'exemple en Perl de @cuonglm donne 31.
  • Utiliser wcdonne 28.

Pour référence, POSIX vi dit:

Dans l'environnement local POSIX, vi reconnaît cinq types de mots:

  1. Une séquence maximale de lettres, chiffres et traits de soulignement, délimitée aux deux extrémités par:

    • Caractères autres que des lettres, des chiffres ou des traits de soulignement

    • Le début ou la fin d'une ligne

    • Le début ou la fin du tampon d'édition

  2. Une séquence maximale de caractères autres que des lettres, des chiffres, des traits de soulignement ou des caractères, délimitée aux deux extrémités par:

    • Une lettre, un chiffre, un trait de soulignement
    • <blank> personnages
    • Le début ou la fin d'une ligne
    • Le début ou la fin du tampon d'édition
  3. Une ou plusieurs lignes vides séquentielles

  4. Le premier caractère du tampon d'édition

  5. Le dernier non <newline>dans le tampon d'édition

Thomas Dickey
la source