Antworten:
$ tr ' ' '\n' < FILE | grep WORD | wc -l
Wenn tr
Leerzeichen durch Zeilenumbrüche ersetzt werden, werden grep
alle resultierenden Zeilen, die mit WORD übereinstimmen, gefiltert und wc
die verbleibenden Zeilen gezählt .
Man kann das wc
Teil sogar mit der -c
Option grep speichern :
$ tr ' ' '\n' < FILE | grep -c WORD
Die -c
Option wird von POSIX definiert.
Wenn nicht garantiert wird, dass zwischen den Wörtern Leerzeichen stehen, müssen Sie ein anderes Zeichen (als Trennzeichen) verwenden, um diese zu ersetzen. Zum Beispiel sind alternative tr
Teile
tr '"' '\n'
oder
tr "'" '\n'
Wenn Sie doppelte oder einfache Anführungszeichen ersetzen möchten. Natürlich können Sie auch tr
mehrere Zeichen gleichzeitig ersetzen (verschiedene Arten von Leerzeichen und Interpunktionszeichen).
Falls Sie WORD, aber nicht prefixWORD, WORDsuffix oder prefixWORDsuffix zählen müssen, können Sie das WORD-Muster in Zeilenanfangs- / Zeilenende-Markierungen einschließen:
grep -c '^WORD$'
Was in unserem Kontext den Wortanfangs- / -ende-Markierungen entspricht:
grep -c '\<WORD\>'
tr
Befehl erstellen, der die Aufgabe erfüllt, anstatt Beispiele vorzuschlagen, die niemals in allen Situationen funktionieren. Es werden auch Wörter gefunden, die das gesuchte Wort enthalten. Die grep -o '\<WORD\>' | wc -l
Lösung ist weit überlegen.
Mit GNU grep funktioniert Folgendes: grep -o '\<WORD\>' | wc -l
-o
druckt alle übereinstimmenden Teile jeder Zeile in eine separate Zeile.
\<
Setzt den Anfang eines Wortes und \>
das Ende eines Wortes (ähnlich wie bei Perl \b
). Dadurch wird sichergestellt, dass Sie keine Zeichenfolge in der Mitte eines Wortes finden.
Zum Beispiel,
$ python -c 'importiere dies' | grep '\ <one \>' Es sollte einen - und am besten nur einen - offensichtlichen Weg geben, dies zu tun. Namespaces sind eine großartige Idee - machen wir mehr davon! $ python -c 'importiere dies' | grep -o '\ <one \>' one one one $ python -c 'importiere dies' | grep -o '\ <one \>' | wc -l 3
grep -wo WORD | wc -l
Dies funktioniert leider nicht mit GNU coreutils
.
grep -o -c WORD file
Wenn es auf Ihrer Plattform funktioniert, ist es eine elegante und recht intuitive Lösung. Aber die GNU-Leute denken immer noch nach.
grep
hier einen Fehler hat. Es ist aus POSIX nicht ersichtlich, welche Semantik beim Kombinieren zu beachten ist -c
und -o
sollte, sodass dies derzeit nicht portierbar ist. Danke für den Kommentar; Ich habe diese Antwort aktualisiert.
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
Dieser Befehl führt Folgendes aus:
Zum Beispiel, wenn ich die erste Linus Torvald-Nachricht analysieren möchte:
Von: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) Newsgroups: comp.os.minix Betreff: Was möchten Sie am liebsten in minix sehen? Zusammenfassung: Kleine Umfrage für mein neues Betriebssystem Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI> Datum: 25. August 91 20:57:08 GMT Organisation: Universität Helsinki
Hallo allerseits mit minix -
Ich mache ein (freies) Betriebssystem (nur ein Hobby, werde nicht so groß und professionell sein wie Gnu) für 386 (486) AT-Klone. Dieses braut seit April und fängt an, fertig zu werden. Ich hätte gerne Feedback zu Dingen, die Leute in Minix mögen / nicht mögen, da mein Betriebssystem dem etwas ähnelt (gleiche physische Anordnung des Dateisystems (unter anderem aus praktischen Gründen)).
Ich habe derzeit bash (1.08) und gcc (1.40) portiert, und die Dinge scheinen zu funktionieren. Dies impliziert, dass ich in ein paar Monaten etwas Praktisches bekomme und ich würde gerne wissen, welche Funktionen die meisten Leute möchten. Vorschläge sind willkommen, aber ich verspreche nicht, dass ich sie umsetzen werde 🙂
Linus (torvalds@kruuna.helsinki.fi)
PS. Ja - es ist frei von jeglichem Minix-Code und es hat ein Multi-Threaded-Fs. Es ist NICHT protable (verwendet 386 Task Switching usw.), und es wird wahrscheinlich nie etwas anderes als AT-Festplatten unterstützen, da das alles ist, was ich habe :-(.
Ich erstelle eine Datei mit dem Namen linus.txt , füge den Inhalt ein und schreibe dann in die Konsole:
sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
Die Ausgabe wäre:
1 7 i
2 5 to
3 5 like
4 5 it
5 5 and
6 4 minix
7 4 a
8 3 torvalds
9 3 of
10 3 helsinki
11 3 fi
12 3 any
13 2 would
14 2 won
15 2 what
16 ...
Wenn Sie nur die ersten 20 Wörter anzeigen möchten:
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20
Es ist wichtig zu beachten, dass der Befehl tr 'AZ' 'a-z' UTF-8 noch nicht unterstützt , sodass das Wort APRÈS in Fremdsprachen als AprÈs übersetzt wird.
Wenn Sie nur nach dem Vorkommen eines Wortes suchen möchten, können Sie am Ende ein Grep einfügen:
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"
In einem Skript namens search_freq :
#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"
Das Skript muss aufgerufen werden:
search_freq word_to_search_for
sed: -e expression #2, char 7: unterminated
s "Befehl", auch das zählt alle Wörter, oder? Aber OP fragte nur einen bestimmten. Auch ein bisschen Erklärung wäre schön.
Je nachdem, ob Sie das Wort in den Schlüsseln oder in den Werten der JSON-Daten abgleichen möchten, möchten Sie wahrscheinlich nur Schlüssel oder nur Werte aus den Daten extrahieren. Andernfalls können Sie einige Wörter zu oft zählen, wenn sie sowohl als Schlüssel als auch als Werte vorkommen.
So extrahieren Sie alle Schlüssel:
jq -r '..|objects|keys[]' <file.json
Dies prüft rekursiv, ob das aktuelle Objekt ein Objekt ist, und wenn dies der Fall ist, werden die Schlüssel extrahiert. Die Ausgabe ist eine Liste von Schlüsseln, eine pro Zeile.
So extrahieren Sie alle Werte:
jq -r '..|scalars' <file.json
Dies funktioniert auf ähnliche Weise, hat jedoch weniger Schritte.
Sie können dann die Ausgabe des obigen Befehls durch grep -c 'PATTERN'
(um ein Muster mit den Schlüsseln oder Werten abzugleichen), oder grep -c -w -F 'WORD'
(um ein Wort in den Schlüsseln oder Werten abzugleichen) oder grep -c -x -F 'WORD'
(um einen vollständigen Schlüssel oder Wert abzugleichen) oder Ähnliches zu leiten Zähle.
Ich habe Json mit so etwas: "number":"OK","number":OK"
mehrmals in einer Zeile wiederholt.
Mein einfacher "OK" Zähler:
sed "s|,|\n|g" response | grep -c OK
Ich habe unter awk Befehl verwendet, um die Anzahl der Vorkommen zu finden
Beispieldatei
Katzendatei1
praveen ajay
praveen
ajay monkey praveen
praveen boy praveen
Befehl:
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
Ausgabe
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
5
awk '{sum+=gsub("praveen","")} END {print sum+0}'
.
{ "key": "the key" }
die Zeichenfolgekey
ein- oder zweimal gezählt werden soll.