2013-02-27 12 views
23

Ich möchte die Anzahl der Wörter aus einer Zeichenfolge mit Shell zählen.How to Count Anzahl der Wörter aus String mit Shell

Angenommen, der String ist:

input="Count from this String" 

Hier ist der Begrenzer Raum ' ' und erwartete Ausgabe ist 4. Es gibt auch Leerzeichen in der Eingabezeichenfolge wie "Count from this String " Hinter sein kann.

Wenn in der Zeichenfolge nachstehendes Leerzeichen vorhanden ist, sollte es die gleiche Ausgabe erzeugen, also 4. Wie kann ich das tun?

+1

Warum Downvote die Frage? Oder bedeutet es, dass wenn jemand etwas nicht weiß und andere es wissen, dann können sie es einfach ablehnen. –

Antwort

30
echo "$input" | wc -w 

Verwenden Sie wc-w, um die Anzahl der Wörter zu zählen.

wc -w <<< "$input" 

Wenn < < < wird nicht von der Shell unterstützt Sie diese Variante ausprobieren können:

Oder wie pro Vorschlag des dogbane kann das Echo los und bekam werden

wc -w << END_OF_INPUT 
$input 
END_OF_INPUT 
+6

Das ist eine [nutzlose Verwendung von Echo] (http://fahdshariff.blogspot.com/2012/12/useless-use-of-echo.html).Verwenden Sie stattdessen 'wc -w <<<" $ input "'. – dogbane

+0

Danke Tuxdude und Dogbane für Ihre Antworten. Wenn ich wc -w <<< "$ input" verwende, erhalte ich einen Fehler: ** Syntaxfehler: habe <&, erwarte Word **. Irgendwelche Ideen? –

+0

Welche Shell laufen Sie? – Tuxdude

27

Sie brauchen keinen externen Befehl wie wc, weil Sie es in reinem bash tun können, die effizienter ist.

Konvertieren der Zeichenfolge in einem Array und dann die Elemente in dem Array zählen:

$ input="Count from this String " 
$ words=($input) 
$ echo ${#words[@]} 
4 

Alternativ verwenden set Positionsparameter zu setzen und sie dann zählen:

$ input="Count from this String " 
$ set -- $input 
$ echo $# 
4 
+3

Die zweite Variante hat einen Nebeneffekt, dass die Positionsparameter überschrieben werden, wie sie von der Befehlszeile empfangen werden oder Parameter, die an eine Funktion übergeben werden (wenn diese Zeilen innerhalb einer Funktion sind). Stellen Sie also sicher, dass Sie sich nach der Verwendung von set nicht auf $ 1, $ 2 usw. verlassen. $ Input – Tuxdude

+0

@Tuxdude Das war sehr wichtig. Danke –

+0

@dogbane Zweite von Ihnen vorgeschlagene Lösung funktioniert gut für mich, aber wie Tuxdude wies darauf hin, ich kann bestehende Parameter nicht durch neue ersetzen, da es den Stromfluss brechen wird. Ich habe versucht, die erste Lösung zu implementieren, aber leider bekomme ich Fehler: ** Syntaxfehler: Got (, erwartet Newline ** –

5

es zu tun in reine bash Nebenwirkungen zu vermeiden, tun sie es in einer Unterschale:

$ input="Count from this string " 
$ echo $(IFS=' '; set -f; set -- $input; echo $#) 
4 

Es arbeitet mit anderen Separatoren auch:

$ input="dog,cat,snake,billy goat,horse" 
$ echo $(IFS=,; set -f; set -- $input; echo $#) 
5 
$ echo $(IFS=' '; set -f; set -- $input; echo $#) 
2 

Beachten Sie die Verwendung von „set -f“, die bash filename expansion in der Subshell deaktiviert, so dass, wenn der Anrufer Expansion will es vorher (Hutspitze @ mkelement0) getan werden soll.

+2

Schön gemacht; Ich schlage vor 'set-f;' zu jedem 'set' Befehl (Hinweis: muss ein sein _separate_ Befehl), um die Pfadnamenerweiterung (vorübergehend) zu deaktivieren. Dies stellt sicher, dass Eingabe-Tokens wie '*' nicht versehentlich erweitert werden. – mklement0

3

Versuchen die folgenden Einzeiler:

echo $(c() { echo $#; }; c $input) 

Er definiert im Grunde c() Funktion und übergibt $input als Argument, dann kehrt $# Anzahl der Elemente in dem Argumente durch Leerzeichen getrennt ist. Um das Trennzeichen zu ändern, können Sie IFS (eine spezielle Variable) ändern.

3
echo "$input" | awk '{print NF}' 
+0

Ich mag die Tatsache, dass mit 'NF-x', wo x eine beliebige Zahl ist, Sie strippen können weg Felder, die nicht gezählt werden sollen. – PdC

0

Ich werde nur mit einem Perl-Einzeiler (Vermeidung von 'nutzlosen Einsatz von echo') läuten:

perl -lane 'print scalar(@F)' <<< $input