Odpowiedzi:
$ tr ' ' '\n' < FILE | grep WORD | wc -l
Gdzie tr
zamienia spacje na nowe linie, grep
filtruje wszystkie wynikowe linie pasujące do WORD i wc
zlicza pozostałe.
Można nawet zapisać wc
część, używając -c
opcji grep:
$ tr ' ' '\n' < FILE | grep -c WORD
-c
Opcja jest zdefiniowany przez POSIX.
Jeśli nie ma gwarancji, że między słowami są spacje, musisz użyć innego znaku (jako separatora) do zastąpienia. Na przykład tr
są części alternatywne
tr '"' '\n'
lub
tr "'" '\n'
jeśli chcesz zastąpić podwójne lub pojedyncze cudzysłowy. Oczywiście możesz także użyć tr
do zamiany wielu znaków jednocześnie (pomyśl o różnych rodzajach białych znaków i interpunkcji).
Jeśli musisz policzyć WORD, ale nie przedrostek WORD, WORDsuffix lub prefixWORDsuffix, możesz zawrzeć wzorzec WORD w znacznikach początku / końca linii:
grep -c '^WORD$'
W naszym kontekście, który jest równoważny znacznikom początku / końca słowa:
grep -c '\<WORD\>'
tr
polecenie, które wykona zadanie, zamiast sugerować przykłady, które nigdy nie będą działać we wszystkich sytuacjach. Dopasuje również słowa zawierające szukane słowo. grep -o '\<WORD\>' | wc -l
Rozwiązanie jest o wiele lepszy.
W przypadku GNU grep działa to: grep -o '\<WORD\>' | wc -l
-o
drukuje każdą dopasowaną część każdej linii na osobnej linii.
\<
potwierdza początek słowa i \>
zapewnia koniec słowa (podobny do Perla \b
), więc zapewnia to, że nie dopasujesz łańcucha w środku słowa.
Na przykład,
$ python -c 'import this' | grep '\ <one \>' Powinien być jeden - a najlepiej tylko jeden - oczywisty sposób na zrobienie tego. Przestrzenie nazw to jeden świetny pomysł - zróbmy ich więcej! $ python -c 'import this' | grep -o '\ <one \>' one one one $ python -c 'import this' | grep -o '\ <one \>' | wc -l 3)
grep -wo WORD | wc -l
To niestety nie działa z GNU coreutils
.
grep -o -c WORD file
Jeśli działa na twojej platformie, jest to eleganckie i dość intuicyjne rozwiązanie; ale ludzie GNU wciąż myślą.
grep
ma tutaj błąd. Nie jest jasne, z POSIX co semantyka łączy -c
i -o
powinno być więc ta obecnie nie jest przenośny. Dziękuję za komentarz; Zaktualizowałem tę odpowiedź.
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
To polecenie sprawia, że:
Na przykład, jeśli chcę przeanalizować pierwszą wiadomość Linusa Torvalda:
Od: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) Grupy dyskusyjne: comp.os.minix Temat: Co chciałbyś zobaczyć w minix? Podsumowanie: mała ankieta dla mojego nowego systemu operacyjnego Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI> Data: 25 sierpnia 91 20:57:08 GMT Organizacja: University of Helsinki
Witajcie wszyscy za pomocą minix -
Robię (darmowy) system operacyjny (po prostu hobby, nie będzie duży i profesjonalny jak GNU) dla 386 (486) AT klonów. Trwa to od kwietnia i zaczyna się przygotowywać. Chciałbym uzyskać informację zwrotną na temat rzeczy, które ludzie lubią / nie lubią w minix, ponieważ mój system operacyjny nieco to przypomina (ten sam fizyczny układ systemu plików (z przyczyn praktycznych) między innymi).
Obecnie przenosiłem bash (1.08) i gcc (1.40) i wydaje się, że wszystko działa. Oznacza to, że w ciągu kilku miesięcy dostanę coś praktycznego i chciałbym wiedzieć, jakie funkcje chciałaby większość ludzi. Wszelkie sugestie są mile widziane, ale nie obiecuję, że je zrealizuję 🙂
Linus (torvalds@kruuna.helsinki.fi)
PS. Tak - nie zawiera żadnego kodu minix i ma wielowątkowy fs. NIE jest to protable (używa przełączania zadań 386 itp.) I prawdopodobnie nigdy nie będzie obsługiwać niczego poza dyskami twardymi AT, ponieważ to wszystko, co mam :-(
Tworzę plik o nazwie linus.txt , wklejam zawartość, a następnie piszę w konsoli:
sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " | tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl
Wyjście byłoby:
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 ...
Jeśli chcesz wizualizować tylko pierwsze 20 słów:
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
Ważne jest, aby pamiętać, że polecenie tr „AZ” „A-Z” nie suport UTF-8 jeszcze tak, że w językach obcych apres słowne byłyby tłumaczone jako Apres.
Jeśli chcesz wyszukać tylko jedno słowo, możesz dodać grep na końcu:
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$"
W skrypcie o nazwie 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$"
Skrypt musi zostać wywołany:
search_freq word_to_search_for
sed: -e expression #2, char 7: unterminated
„polecenie”, to także liczy wszystkie słowa, prawda? Ale OP poprosił tylko o jeden. Przydałoby się również trochę wyjaśnienia.
W zależności od tego, czy chcesz dopasować słowo w kluczach, czy w wartościach danych JSON, prawdopodobnie będziesz chciał wyodrębnić tylko klucze lub tylko wartości z danych. W przeciwnym razie możesz przeliczyć niektóre słowa zbyt wiele razy, jeśli występują zarówno jako klucze, jak i wartości.
Aby wyodrębnić wszystkie klucze:
jq -r '..|objects|keys[]' <file.json
To rekurencyjnie sprawdza, czy bieżąca rzecz jest obiektem, a jeśli tak, to wyodrębnia klucze. Wynikiem będzie lista kluczy, po jednym w wierszu.
Aby wyodrębnić wszystkie wartości:
jq -r '..|scalars' <file.json
Działa to w podobny sposób, ale ma mniej kroków.
Następnie możesz potokować wynik powyższego grep -c 'PATTERN'
(aby dopasować jakiś wzorzec do kluczy lub wartości), lub grep -c -w -F 'WORD'
(aby dopasować słowo w kluczach lub wartościach), lub grep -c -x -F 'WORD'
(aby dopasować pełny klucz lub wartość), lub podobny, do licz swoje.
Mam JSON z czymś takim: "number":"OK","number":OK"
powtarzane wiele razy w jednym wierszu.
Mój prosty licznik „OK”:
sed "s|,|\n|g" response | grep -c OK
Użyłem poniżej polecenia awk, aby znaleźć liczbę wystąpień
przykładowy plik
plik kota 1
praveen ajay
praveen
ajay monkey praveen
praveen boy praveen
Komenda:
awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'
wynik
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" }
powinno liczyć ciągkey
raz czy dwa razy.