it-swarm-eu.dev

Jak mohu spočítat počet výskytů slova v textovém souboru pomocí příkazového řádku?

Mám velký soubor JSON, který je na jednom řádku, a chci použít příkazový řádek, aby bylo možné spočítat počet výskytů slova v souboru. Jak to mohu udělat?

45
mythz
$ tr ' ' '\n' < FILE | grep Word | wc -l

Kde tr nahradí mezery novými řádky, grep filtruje všechny výsledné řádky odpovídající Wordu a wc počítá zbývající.

Část wc lze dokonce uložit pomocí -c možnost grep:

$ tr ' ' '\n' < FILE | grep -c Word

The -c volba je definována POSIX.

Pokud není zaručeno, že mezi slovy jsou mezery, je třeba použít jiný znak (jako oddělovač). Například alternativní tr části jsou

tr '"' '\n'

nebo

tr "'" '\n'

pokud chcete nahradit dvojité nebo jednoduché uvozovky. Samozřejmě můžete také použít tr k nahrazení více znaků najednou (například různé druhy mezer a interpunkce).

V případě, že potřebujete počítat Word, ale ne předponu WORD, WORDsuffix nebo prefixWORDsuffix, můžete uzavřít vzorec Word do značek začátku/konce řádku:

grep -c '^Word$'

Což je v našem kontextu ekvivalentní se značkami začátku/konce slov:

grep -c '\<Word\>'
48
maxschlepzig

S GNU grep) to funguje: grep -o '\<Word\>' | wc -l

-o vytiskne každou odpovídající část každého řádku na samostatném řádku.

\< potvrzuje začátek slova a \> potvrzuje konec slova (podobně jako Perl's \b), takže je zajištěno, že neodpovídáte řetězci uprostřed slova Word.

Například,

$ python -c 'importovat toto' | grep '\ <one \>' 
 jeden- a pokud možno pouze jeden --objevný způsob, jak to udělat. 
 Jmenné prostory jsou jeden skvělý nápad - udělejme více z nich! 
$ python -c 'importovat toto' | grep -o '\ <one \>' 
jedenjedenjeden$ python -c 'importovat toto' | grep -o '\ <one \>' | wc -l 
 3 
25
ephemient

To bohužel nefunguje s GNU coreutils.

grep -o -c Word file

Pokud to funguje na vaší platformě, je to elegantní a celkem intuitivní řešení; ale GNU lidé si stále myslí.

11
tripleee
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 

Tento příkaz provede následující:

  1. Nahraďte všechny nealfanumerické znaky mezerou.
  2. Všechny konce řádků jsou také převedeny na mezery.
  3. Redukuje všechny více mezer na jedno prázdné místo
  4. Všechny mezery jsou nyní převedeny na konce řádků. Každé slovo v řadě.
  5. Překládá všechna slova na malá písmena, aby se předešlo odlišným slovům „Hello“ a „Hello“
  6. Třídí text
  7. Počítá a odstraní stejné řádky
  8. Třídí se obráceně, aby se počítala nejčastější slova
  9. Ke každému slovu přidejte číslo řádku, abyste se dozvěděli, jak se celé slovo nachází

Například pokud chci analizovat první zprávu Linuse Torvalda:

Od: [email protected] (Linus Benedict Torvalds) Newsgroups: comp.os.minix Předmět: Co byste chtěli vidět nejvíce v minixu? Shrnutí: malý průzkum pro můj nový operační systém Zpráva ID: <[email protected]> Datum: 25. srpna 91 20:57:08 GMT Organizace: University of Helsinki

Ahoj všichni tam pomocí minix -

Dělám (volný) operační systém (jen koníček, nebudu velký a profesionální jako gnu) pro 386 (486) AT klonů). Pivovarnictví se vaří od dubna a Začíná se připravovat. Chtěl bych jakoukoli zpětnou vazbu o věcech, které se lidem v minixu líbí/nelíbí, protože můj operační systém se poněkud podobá (mimo jiné stejného fyzického rozložení souborového systému (z praktických důvodů)).

V současné době jsem přenesl bash (1.08) a gcc (1.40) a zdá se, že věci fungují. To znamená, že během několika měsíců dostanu něco praktického a rád bych věděl, jaké funkce by většina lidí chtěla. Jakékoli návrhy jsou vítány, ale neslibuji, že je implementuji ????

Linus (t[email protected])

PS. Ano - neobsahuje žádný kód minix a má vícevláknové fs. NENÍ chráněno (používá 386 přepínání úkolů atd.) A pravděpodobně nikdy nebude podporovat nic jiného než pevné disky AT, protože to je všechno, co mám : .

Vytvářím soubor s názvem linus.txt , vložím obsah a poté píšu do konzole:

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

Výsledkem by bylo:

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

Pokud si chcete představit pouze prvních 20 slov:

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

Je důležité si uvědomit, že příkaz tr 'AZ' 'a-z' nepodporuje UTF-8 --- (zatím , takže v cizích jazycích bude slovo APRÈS přeloženo jako aprís.

Pokud chcete hledat pouze výskyt jednoho slova, můžete na konec přidat grep:

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$"

Ve skriptu s názvem 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$"

Skript musí být nazýván:

 search_freq Word_to_search_for
7
Roger Borrell

V závislosti na tom, zda chcete shodovat slovo v klávesách nebo v hodnotách dat JSON, budete pravděpodobně chtít z dat extrahovat pouze klíče nebo pouze hodnoty. Jinak můžete počítat některá slova příliš mnohokrát, pokud se vyskytnou jako klíče i hodnoty.

Extrahování všech klíčů:

jq -r '..|objects|keys[]' <file.json

To rekurzivně testuje, zda je aktuální věc objektem, a pokud ano, extrahuje klíče. Výstupem bude seznam klíčů, jeden na řádek.

Chcete-li extrahovat všechny hodnoty:

jq -r '..|scalars' <file.json

Funguje to podobným způsobem, ale má méně kroků.

Potom můžete posílat výstup z výše uvedeného skrz grep -c 'PATTERN' (k porovnání některých vzorů s klávesami nebo hodnotami) nebo grep -c -w -F 'Word' (v klíčích nebo hodnotách odpovídá Word) nebo grep -c -x -F 'Word' (aby odpovídal úplnému klíči nebo hodnotě) nebo podobné, aby se provedlo počítání.

3
Kusalananda

Mám něco podobného: "number":"OK","number":OK" opakováno vícekrát v jednom řádku.

Můj jednoduchý čítač „OK“:

sed "s|,|\n|g" response | grep -c OK

0

Použitím grep -c budete počítat pouze řádky, jeden řádek může mít mnoho výskytů Slova.

To by to provedlo:

grep -o Word foo|wc -l
0
Ramiro Velazquez