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 imprimer 5
, car il y a 5
mots là-bas.
La commande wc
aka. Le nombre de mots peut le faire:
$ 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
Je suis venu avec cela pour JUSTE le nombre:
wc -w [file] | cut -d' ' -f1
5
J'aime aussi le 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.
Le programme wc
compte les "mots", mais ce ne sont pas par exemple les "mots" que beaucoup de gens verraient en examinant un fichier. Le programme vi
, par exemple, utilise une mesure différente des "mots", les délimitant en fonction de leurs classes de caractères, tandis que wc
compte simplement les choses séparées par des espaces . Les deux mesures peuvent être radicalement différentes. Considérez cet exemple:
first,second
vi
voit trois mots ( premier et second comme ainsi que la virgule qui les sépare), tandis que wc
en voit 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.
Bien que Perl soit mieux adapté à l'écriture d'un compteur pour les mots de style vi, voici un exemple rapide utilisant sed
, tr
et wc
(modérément portable à l'aide de 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:
wc
donne 28.Pour référence, POSIX vi dit:
Dans l'environnement local POSIX, vi reconnaît cinq types de mots:
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
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>
caractères- Le début ou la fin d'une ligne
- Le début ou la fin du tampon d'édition
Une ou plusieurs lignes vides séquentielles
Le premier caractère du tampon d'édition
Le dernier non -
<newline>
dans le tampon d'édition
$ 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 vous avez demandé, mais c'est mieux! Si vous voulez voir les occurrences de votre Word, vous pouvez simplement faire ceci:
$ cat your_file.txt | wordfrequency | grep yourword
J'ai même ajouté cette fonction à mes . Dotfiles
Source: Rubis AWK-ward
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 commande wc
de coreutils, je teste dans ma machine, avec le fichier subst.c
dans la source bash 4.2.
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
.