Wie wird die Gesamtzahl der Wörter in einer Datei gezählt?

18

Ich suche einen Befehl, um die Anzahl aller Wörter in einer Datei zu zählen. Zum Beispiel, wenn eine Datei wie folgt ist,

today is a 
good day

dann sollte es drucken 5, da es dort 5Wörter gibt.

Richard
quelle
7
Hast du es versucht wc -w $FILE?
don_crissti

Antworten:

39

Der Befehl wcaka. Wortzählung kann es tun:

$ wc -w <file>

Beispiel

$ 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
quelle
1
Beachten Sie, dass Wörter für wc -wnicht die gleiche Definition haben wie für GNU grep -w. Für wcein Wort ist eine Folge von einem oder mehrere nicht-Leerzeichen ( [:space:]Zeichenklasse im aktuellen locale). Zum Beispiel foo,barund foo bar(mit einem nicht unterbrechenden Leerzeichen) sind jeweils ein Wort.
Stéphane Chazelas
7

Ich habe mir dazu NUR die Nummer ausgedacht:

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

5

Mir gefällt auch der wc -w < [file]Ansatz

Zum Speichern nur der Wortanzahl in einer Variablen können Sie Folgendes verwenden:

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

Auf diese Weise können Sie den Dateinamen elegant überspringen.

Michael Durrant
quelle
14
wc -w < "$file"für nur die Nummer.
Stéphane Chazelas
3

Die bessere Lösung ist die Verwendung von Perl:

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

@Bernhard

Sie können den Quellcode des wcBefehls mit coreutils überprüfen , den ich auf meinem Computer subst.cteste. Die Datei befindet sich in der Bash 4.2-Quelle.

time wc -w subst.c

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

Und

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

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

Je größer die Datei ist, desto effizienter ist Perl in Bezug auf wc.

cuonglm
quelle
13
Warum ist das besser als wc?
Sparr
2
@Sparr zum einen, weil es zu meiner großen Überraschung viel schneller zu sein scheint . Ich habe es mit einer Textdatei mit 141813504 Wörtern versucht und wc~ 14 Sekunden gebraucht, während Perl ~ 5 Sekunden gebraucht hat!
terdon
3
Ich denke, das größere Problem ist wirklich eine Antwort, die von Perl abhängt, und ich bin nie ein großer Fan einer solchen Abhängigkeit. Wenn es um Leistung ging, wäre das eine andere Sache.
Michael Durrant
5
Beachten Sie, dass ein splitauf /\s+/wie eine ist , split(' ')außer dass jedes führendes Leerzeichen eine Null erste Feld erzeugt. Dieser Unterschied wird Ihnen ein zusätzliches Wort (die Null erste Feld, das ist) pro Zeile Link . Verwenden Sie (split(" ", $_))für eine so erstellte Datei etwas anderes: echo -e "unix\n linux" > testfileIhr Einzeiler meldet 3 Wörter.
don_crissti
1
Ihre Timings zeigen, dass wc schneller ist (es sind Benutzer- und Systemzeiten, die dort eine Rolle spielen). Mit LC_ALL = C wcwird deutlich schneller, genau wie mit PERLIO=:utf8, perlwird deutlich langsamer.
Stéphane Chazelas
3

Lass uns AWK benutzen!

$ 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

Dies listet die Häufigkeit jedes Wortes auf, das in der bereitgestellten Datei vorkommt. Ich weiß, es ist nicht das, wonach du gefragt hast, aber es ist besser! Wenn Sie die Vorkommen Ihres Wortes sehen möchten, können Sie dies einfach tun:

$ cat your_file.txt | wordfrequency | grep yourword

Ich habe diese Funktion sogar zu meinen .dot-Dateien hinzugefügt


Quelle: AWK-Station Ruby

Sheharyar
quelle
Es zählt Worte, also ist es gut genug für mich! :-)
aggsol
3

Das wcProgramm zählt "Wörter", aber dies sind beispielsweise nicht die "Wörter", die viele Leute sehen würden, wenn sie eine Datei untersuchen. Das viProgramm verwendet zum Beispiel ein anderes Maß für "Wörter", das sie basierend auf ihren Zeichenklassen abgrenzt, während wceinfach durch Leerzeichen getrennte Dinge gezählt werden . Die beiden Maßnahmen können sich radikal unterscheiden. Betrachten Sie dieses Beispiel:

first,second

visieht drei Wörter ( erste und zweite sowie die sie trenn Komma), während wcsieht man (kein Leerzeichen auf dieser Linie ist). Es gibt viele Möglichkeiten, Wörter zu zählen. Einige sind weniger nützlich als andere.

Während Perl wäre besser zu schreiben einen Zähler für die vi-Stil Worte geeignet sein, hier ist ein kurzes Beispiel mit sed, trund wc(mäßig tragbarer wörtlichen Wagenrücklauf mit ^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

Zählungen vergleichen:

  • Das Ausführen des Skripts auf sich selbst gibt mir 76 Wörter.
  • Das Beispiel in Perl von @cuonglm ergibt 31.
  • Verwenden wcgibt 28.

Als Referenz sagt POSIX vi :

Im POSIX-Gebietsschema erkennt vi fünf Arten von Wörtern:

  1. Eine maximale Folge von Buchstaben, Ziffern und Unterstrichen, die an beiden Enden durch Folgendes begrenzt sind:

    • Andere Zeichen als Buchstaben, Ziffern oder Unterstriche

    • Der Anfang oder das Ende einer Zeile

    • Der Anfang oder das Ende des Bearbeitungspuffers

  2. Eine maximale Folge von anderen Zeichen als Buchstaben, Ziffern, Unterstrichen oder Zeichen, die an beiden Enden durch Folgendes begrenzt sind:

    • Ein Buchstabe, eine Ziffer, ein Unterstrich
    • <blank> Zeichen
    • Der Anfang oder das Ende einer Zeile
    • Der Anfang oder das Ende des Bearbeitungspuffers
  3. Eine oder mehrere aufeinanderfolgende Leerzeilen

  4. Das erste Zeichen im Bearbeitungspuffer

  5. Das letzte nicht <newline>im Bearbeitungspuffer

Thomas Dickey
quelle