Ottieni il conteggio delle occorrenze delle parole nel file di testo di tutte le parole e stampa l'output ordinato


28

Ho avuto un comando che avrebbe funzionato attraverso un file di testo, contando tutte le occorrenze delle parole e stampandolo in questo modo:

user@box $˜ magic-command-i-forgot | with grep | and awk | sort ./textfile.txt
66: the
54: and
32: I
16: unix
12: bash
5:  internet
3:  sh
1: GNU/Linux

Quindi non cerca riga per riga, ma parola per parola, e lo fa per tutte le parole, non solo per 1 parola. L'avevo trovato da qualche parte su Internet molto tempo fa, ma non riesco a trovarlo o ricordarlo.

Risposte:


33

Vorrei usare trinvece di awk :

echo "Lorem ipsum dolor sit sit amet et cetera." | tr '[:space:]' '[\n*]' | grep -v "^\s*$" | sort | uniq -c | sort -bnr
  • tr sostituisce semplicemente gli spazi con newline
  • grep -v "^\s*$" taglia le righe vuote
  • sort per preparare come input per uniq
  • uniq -c per contare le occorrenze
  • sort -bnr ordina in ordine numerico inverso ignorando gli spazi bianchi

Wow. si è rivelato un ottimo comando per contare le imprecazioni per riga

trova . -name "* .py" -exec cat {} \; | tr '[: space:]' '[\ n *]' | grep -v "^ \ s * $" | ordina | uniq -c | ordina -bnr | cazzo grep


Potrebbe voler usare tr -sper gestire più spazi, soprattutto quando si incontrano rientri.
Arcege,

@Arcege: buon punto. Anche se non cambierà il risultato, potrebbe fissare un po 'lo script.
seler

-g( --general-numeric-sort) L'opzione di sortpuò essere preferibile in alcuni casi. Ad esempio sort -n, manterrà 10\n1 4com'è, trattando 1 4come 14, mentre sort -glo tratterà correttamente come 1 4\n10.
Skippy le Grand Gourou,

bel comando, merita davvero un voto in più :)
Noor

@seler Penso che tu possa rendere la parte grep e tr ancora più semplice come di seguito: echo "Lorem ipsum dolor sit sit amet et cetera." | tr ' ' '\n' | grep -v "^$" | sort | uniq -c | sort -bnrNota che sono un principiante, quindi potrei sbagliarmi, non esitare a consigliarti.
smc,

8
  1. Dividi l'input in parole, una per riga.
  2. Ordina l'elenco risultante di parole (righe).
  3. Schiaccia più ricorrenze.
  4. Ordina per numero di occorrenze.

Per dividere l'input in parole, sostituisci qualsiasi carattere che ritieni sia un separatore di parole con una nuova riga.

<input_file \
tr -sc '[:alpha:]' '[\n*]' | # Add digits, -, ', ... if you consider
                             # them word constituents
sort |
uniq -c |
sort -nr

Questa è una bella risposta perché può gestire il caso in cui le parole si trovano direttamente accanto ad alcuni segni di punteggiatura che non vuoi ignorare.
David Grayson,

5

Non usare grep e awk ma questo sembra fare quello che vuoi:

for w in `cat maxwell.txt`; do echo $w; done|sort|uniq -c
  2 a
  1 A
  1 an
  1 command
  1 considered
  1 domain-specific
  1 for
  1 interpreter,
  2 is
  1 language.
  1 line
  1 of

1
Questo non funzionerà se l'input contiene caratteri jolly della shell (è necessario aggiungere set -f ) e considera la punteggiatura come parte delle parole (che può essere risolta in modo improprio aggiungendo caratteri di punteggiatura a IFS- buona fortuna cercando di supportare set di caratteri non ASCII). Questo non va bene con file di input molto grandi, poiché memorizza l'intero file in memoria ( sortè più intelligente).
Gilles 'SO- smetti di essere malvagio'

2

Credo che tu stia cercando qualcosa del genere?

$ perl -n -e 'foreach ${k} (split(/\s+/)){++$h{$k}};END{foreach $l (keys(%h)){print "$h{$l}: ${l}\n"}}' /path/to/your/file | sort -n -k 1

ovviamente puoi fare lo stesso anche con awk:)


2

utilizzando awk/sort/uniq soluzione:

awk '{for(w=1;w<=NF;w++) print $w}' ~/textFile.txt | sort | uniq -c | sort -nr

Bellissimo! Questo ha funzionato perfettamente.
Stidmatt,

0
file=/home/stefan/ooxml1.txt
for word in $(sed 's/[^A-Za-z]/ /g' $file | tr " " "\n" | sort -u)
do
  echo -n "$word "
  grep -c $word $file
done | sort -k2 -n 

ordina in ordine crescente dopo aver diviso il file in parole.

Il semplice grep troverà fish in fisheye, in modo da avere per aumentare il comando grep per evitare corrispondenze parziali.

Richiede circa 3 secondi per un file di testo di 25k su una macchina nei secoli, HDD classico (IDE).

Per i file più grandi o le operazioni eseguite spesso, sarebbe meglio un approccio con mappa hash, ma per un lavoro raramente eseguito o solo file più piccoli, potrebbe essere sufficiente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.