Sto cercando un comando per contare il numero di tutte le parole in un file. Ad esempio se un file è così,
today is a
good day
quindi dovrebbe stampare 5
, poiché ci sono 5
parole lì.
Sto cercando un comando per contare il numero di tutte le parole in un file. Ad esempio se un file è così,
today is a
good day
quindi dovrebbe stampare 5
, poiché ci sono 5
parole lì.
Risposte:
Il comando wc
aka. il conteggio delle parole può farlo:
$ 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
non hanno la stessa definizione di GNU grep -w
. Perché wc
una parola è una sequenza di uno o più caratteri non spaziali ( [:space:]
classe di caratteri nella locale corrente). Ad esempio foo,bar
e foo bar
(con uno spazio non-break) sono ciascuna una parola.
Ho pensato a questo per SOLO il numero:
wc -w [file] | cut -d' ' -f1
5
Mi piace anche l' wc -w < [file]
approccio
Infine, per memorizzare solo il conteggio delle parole in una variabile, è possibile utilizzare quanto segue:
myVar=($(wc -w /path/to/file))
Ciò ti consente di saltare il nome del file in modo elegante.
wc -w < "$file"
per SOLO il numero.
La soluzione migliore sta usando Perl:
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@Bernhard
Puoi controllare il codice sorgente del wc
comando da coreutils, lo collaudo nella mia macchina, con il file subst.c
nel codice sorgente 4.2.
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
Più grande è il file, più efficiente è Perl rispetto a wc
.
wc
preso ~ 14sec mentre Perl ha preso ~ 5sec!
split
on /\s+/
è come un split(' ')
tranne che uno spazio bianco iniziale produce un primo campo nullo. Questa differenza ti darà una parola in più (il primo campo nullo, cioè) per collegamento di linea . Quindi usa (split(" ", $_))
altrimenti per un file creato in questo modo: il echo -e "unix\n linux" > testfile
tuo one-liner riporta 3 parole.
wc
sarà significativamente più veloce, proprio come con PERLIO=:utf8
, perl
sarà significativamente più 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
Questo elenca la frequenza di ciascuna parola presente nel file fornito. So che non è quello che hai chiesto, ma è meglio! Se vuoi vedere le occorrenze della tua parola, puoi semplicemente fare questo:
$ cat your_file.txt | wordfrequency | grep yourword
Ho persino aggiunto questa funzione ai miei file .dot
Fonte: AWK-ward Ruby
Il wc
programma conta "parole", ma quelle non sono ad esempio le "parole" che molte persone vedrebbero quando esaminano un file. Ad vi
esempio, il programma utilizza una diversa misura di "parole", delimitandole in base alle loro classi di caratteri, mentre wc
conta semplicemente le cose separate da spazi bianchi . Le due misure possono essere radicalmente diverse. Considera questo esempio:
first,second
vi
vede tre parole ( prima e seconda così come la virgola che le separa), mentre ne wc
vede una (non c'è spazio bianco su quella linea). Esistono molti modi per contare le parole, alcune sono meno utili di altre.
Mentre Perl sarebbe più adatto a scrivere un contatore per le parole in stile vi, ecco un rapido esempio usando sed
, tr
e wc
(moderatamente portatile usando i ritorni a capo letterali ^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
Confronto dei conteggi:
wc
dà 28.Per riferimento, POSIX vi dice:
Nella locale POSIX, vi deve riconoscere cinque tipi di parole:
Una sequenza massima di lettere, cifre e caratteri di sottolineatura, delimitata ad entrambe le estremità da:
Caratteri diversi da lettere, cifre o caratteri di sottolineatura
L'inizio o la fine di una riga
L'inizio o la fine del buffer di modifica
Una sequenza massima di caratteri diversi da lettere, cifre, caratteri di sottolineatura o caratteri, delimitati ad entrambe le estremità da:
- Una lettera, cifra, carattere di sottolineatura
<blank>
personaggi- L'inizio o la fine di una riga
- L'inizio o la fine del buffer di modifica
Una o più righe vuote sequenziali
Il primo carattere nel buffer di modifica
L'ultimo non
<newline>
nel buffer di modifica
wc -w $FILE
?