come contare il numero totale di parole in un file?


Risposte:


39

Il comando wcaka. il conteggio delle parole può farlo:

$ wc -w <file>

esempio

$ 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
Nota che le parole per wc -wnon hanno la stessa definizione di GNU grep -w. Perché wcuna parola è una sequenza di uno o più caratteri non spaziali ( [:space:]classe di caratteri nella locale corrente). Ad esempio foo,bare foo bar(con uno spazio non-break) sono ciascuna una parola.
Stéphane Chazelas,

7

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.


14
wc -w < "$file"per SOLO il numero.
Stéphane Chazelas,

3

La soluzione migliore sta usando Perl:

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

@Bernhard

Puoi controllare il codice sorgente del wccomando da coreutils, lo collaudo nella mia macchina, con il file subst.cnel 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.


13
Perché è meglio del wc?
Sparr,

2
@Sparr per prima cosa perché, con mia grande sorpresa, sembra essere molto più veloce. L'ho provato su un file di testo con 141813504 parole e ho wcpreso ~ 14sec mentre Perl ha preso ~ 5sec!
terdon

3
Penso che il problema "più grande" sia davvero una risposta che ha una dipendenza da Perl e non sono mai un grande fan di tale dipendenza. Se la domanda riguardasse le prestazioni sarebbe un'altra cosa.
Michael Durrant,

5
Nota che un spliton /\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" > testfiletuo one-liner riporta 3 parole.
don_crissti,

1
I tuoi tempi mostrano che wc è più veloce (sono i tempi utente e sistema che contano lì). Con LC_ALL = C, wcsarà significativamente più veloce, proprio come con PERLIO=:utf8, perlsarà significativamente più lento.
Stéphane Chazelas,

3

Usiamo 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

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


Conta le parole, quindi è abbastanza buono per me! :-)
aggsol,

3

Il wcprogramma conta "parole", ma quelle non sono ad esempio le "parole" che molte persone vedrebbero quando esaminano un file. Ad viesempio, il programma utilizza una diversa misura di "parole", delimitandole in base alle loro classi di caratteri, mentre wcconta semplicemente le cose separate da spazi bianchi . Le due misure possono essere radicalmente diverse. Considera questo esempio:

first,second

vivede tre parole ( prima e seconda così come la virgola che le separa), mentre ne wcvede 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, tre 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:

  • Eseguire lo script su se stesso, mi dà 76 parole.
  • L'esempio in Perl di @cuonglm fornisce 31.
  • Usare wcdà 28.

Per riferimento, POSIX vi dice:

Nella locale POSIX, vi deve riconoscere cinque tipi di parole:

  1. 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

  2. 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
  3. Una o più righe vuote sequenziali

  4. Il primo carattere nel buffer di modifica

  5. L'ultimo non <newline>nel buffer di modifica

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.