it-swarm.it

Come contare il numero di occorrenze di una parola in un file di testo con la riga di comando?

Ho un grande file JSON che si trova su una riga e desidero utilizzare la riga di comando per poter contare il numero di occorrenze di una parola nel file. Come lo posso fare?

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

Dove tr sostituisce gli spazi con newline, grep filtra tutte le righe risultanti che corrispondono a Word e wc conta le restanti.

Si può anche salvare la parte wc usando -c opzione di grep:

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

Il -c L'opzione è definita da POSIX.

Se non è garantito che ci siano spazi tra le parole, devi sostituire qualche altro carattere (come delimitatore). Ad esempio, le parti alternative tr sono

tr '"' '\n'

o

tr "'" '\n'

se vuoi sostituire le virgolette doppie o singole. Ovviamente, puoi anche usare tr per sostituire più caratteri contemporaneamente (pensa a diversi tipi di spazi bianchi e punteggiatura).

Nel caso in cui sia necessario contare Word ma non prefixWORD, WORDsuffix o prefixWORDsuffix, è possibile racchiudere il modello di Word nei marcatori di inizio/fine riga:

grep -c '^Word$'

Che è equivalente ai marcatori di inizio/fine di Word, nel nostro contesto:

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

Con GNU grep, funziona: grep -o '\<Word\>' | wc -l

-o Stampa ogni parte corrispondente di ogni riga su una riga separata.

\< Afferma l'inizio di una Parola e \> Afferma la fine di una Parola (simile a \b Di Perl), quindi questo assicura che non abbini una stringa nel nel mezzo di una parola.

Per esempio,

$ python -c 'import this' | grep '\ <one \>' 
 Dovrebbero esserci uno- e preferibilmente solo uno --Operoso modo di farlo. 
 Gli spazi dei nomi sono uno clacson ottima idea - facciamo di più! 
$ python -c 'importa questo' | grep -o '\ <one \>' 
unounouno$ python -c 'importa questo' | grep -o '\ <one \>' | wc -l 
 3 
25
ephemient

Questo purtroppo non funziona con GNU coreutils.

grep -o -c Word file

Se funziona sulla tua piattaforma, è una soluzione elegante e abbastanza intuitiva; ma il GNU la gente sta ancora pensando.

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 

Questo comando effettua quanto segue:

  1. Sostituisci tutti i caratteri non alfanumerici con uno spazio vuoto.
  2. Anche tutte le interruzioni di riga vengono convertite in spazi.
  3. Riduce tutti gli spazi vuoti multipli in uno spazio vuoto
  4. Tutti gli spazi vengono ora convertiti in interruzioni di riga. Ogni parola in una riga.
  5. Traduce tutte le parole in minuscolo per evitare che "Hello" e "Hello" siano parole diverse
  6. Ordina testo
  7. Conta e rimuove le linee uguali
  8. Ordina al contrario per contare le parole più frequenti
  9. Aggiungi un numero di riga a ciascuna Parola per conoscere la posotion della Parola nel suo insieme

Ad esempio, se voglio analizzare il primo messaggio di Linus Torvald:

Da: [email protected] (Linus Benedict Torvalds) Newsgroup: comp.os.minix Oggetto: Cosa ti piacerebbe vedere di più in minix? Riepilogo: piccolo sondaggio per il mio nuovo sistema operativo ID messaggio: <[email protected]> Data: 25 ago 91 20:57:08 GMT Organizzazione: Università di Helsinki

Ciao a tutti là fuori usando minix -

Sto facendo un sistema operativo (gratuito) (solo un hobby, non sarà grande e professionale come gnu) per 386 (486) AT cloni. Questo è stato preparato da aprile, e sta iniziando a prepararsi. Vorrei un feedback su cose che piacciono o non piacciono alle persone in minix, dal momento che il mio sistema operativo assomiglia in qualche modo (stesso layout fisico del file system (per motivi pratici) tra le altre cose).

Al momento ho eseguito il porting di bash (1.08) e gcc (1.40) e le cose sembrano funzionare. Ciò implica che entro pochi mesi avrò qualcosa di pratico e mi piacerebbe sapere quali funzionalità la maggior parte delle persone vorrebbe. Eventuali suggerimenti sono ben accetti, ma non prometto che li implementerò ????

Linus ([email protected])

PS. Sì, è privo di qualsiasi codice minix e ha un fs multi-thread. NON è protetto (utilizza 386 task switching ecc.) E probabilmente non supporterà mai nulla di diverso dai dischi rigidi AT, poiché è tutto ciò che ho : .

Creo un file chiamato linus.txt , incollo il contenuto e quindi scrivo nella console:

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

L'out messo sarebbe:

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

Se vuoi visualizzare solo le prime 20 parole:

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

È importante notare che il comando tr 'AZ' 'a-z' non supporta UTF-8 --- (ancora , in modo che nelle lingue straniere la parola APRÈS venga tradotta come aprÈs.

Se vuoi solo cercare la ricorrenza di una parola, puoi aggiungere un grep alla fine:

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 uno script chiamato 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$"

Lo script deve essere chiamato:

 search_freq Word_to_search_for
7
Roger Borrell

A seconda che si desideri abbinare la parola nelle chiavi o nei valori dei dati JSON, è probabile che si desideri estrarre solo le chiavi o solo i valori dai dati. In caso contrario, potresti contare alcune parole troppe volte se si presentano sia come chiavi che come valori.

Per estrarre tutte le chiavi:

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

Questo verifica in modo ricorsivo se la cosa corrente è un oggetto e, se lo è, estrae le chiavi. L'output sarà un elenco di chiavi, una per riga.

Per estrarre tutti i valori:

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

Funziona in modo simile, ma ha meno passaggi.

È quindi possibile reindirizzare l'output di quanto sopra tramite grep -c 'PATTERN' (per abbinare un motivo a chiavi o valori) o grep -c -w -F 'Word' (per abbinare un Word nelle chiavi o nei valori) oppure grep -c -x -F 'Word' (per abbinare una chiave o un valore completi) o simili, per eseguire il conteggio.

3
Kusalananda

Ho json con qualcosa del genere: "number":"OK","number":OK" ripetuto più volte in una riga.

Il mio semplice contatore "OK":

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

0

Utilizzando grep -c conterai solo le righe, una riga potrebbe avere molte occorrenze della Parola.

Questo lo farebbe:

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