Successivo: Programma riordino diario, Precedente: Programma labels, Su: Programmi vari [Contenuti][Indice]
Quando si lavora con una grande quantità di testo, può essere interessante sapere quanto spesso ricorrono le diverse parole. Per esempio, un autore può fare un uso eccessivo di certe parole, e in questo caso si potrebbero trovare sinonimi da sostituire a parole che appaiono troppo spesso. Questa sottosezione spiega come scrivere un programma per contare le parole e presentare in un formato utile le informazioni relative alla loro frequenza.
A prima vista, un programma come questo sembrerebbe essere sufficiente:
# wordfreq-first-try.awk --- stampa lista frequenze utilizzo parole { for (i = 1; i <= NF; i++) freq[$i]++ }
END { for (word in freq) printf "%s\t%d\n", word, freq[word] }
Il programma si affida al meccanismo con cui awk
divide i campi per
default, per suddividere ogni riga in “parole” e usa un vettore associativo
di nome freq
, che ha per indici le singole parole, per contare il
numero di volte che ogni parola viene usata. Nella regola END
, stampa i
contatori.
Questo programma ha parecchi problemi che lo rendono praticamente inutile su file di testo reali:
awk
considera i caratteri maiuscoli e minuscoli come
distinti (non equivalenti). Quindi, “barista” e “Barista” sono
considerate parole differenti. Questo non è un comportamento auspicabile,
perché le parole iniziano con la lettera maiuscola se sono a inizio frase in
un testo normale, e un analizzatore di frequenze dovrebbe ignorare la
distinzione maiuscolo/minuscolo.
awk
secondo cui i
campi sono separati solo da spazi bianchi. Altri caratteri nell’input
(tranne il ritorno a capo) non hanno alcun particolare significato per
awk
. Questo significa che i segni di interpunzione sono visti come
parte di una parola.
Il primo problema si può risolvere usando tolower()
per rimuovere la
distinzione maiuscolo/minuscolo. Il secondo problema si può risolvere usando
gsub()
per rimuovere i caratteri di interpunzione. Infine, per
risolvere il terzo problema si può usare il programma di utilità
sort
per elaborare l’output dello script awk
. Ecco la
nuova versione del programma:
# wordfreq.awk --- stampa la lista con la frequenza delle parole { $0 = tolower($0) # togli maiuscolo/minuscolo # togli interpunzione gsub(/[^[:alnum:]_[:blank:]]/, "", $0) for (i = 1; i <= NF; i++) freq[$i]++ } END { for (word in freq) printf "%s\t%d\n", word, freq[word] }
La regexp /[^[:alnum:]_[:blank:]]/
si poteva scrivere come
/[[:punct:]]/
, ma in questo modo il caratteri trattino basso sarebbe
stato rimosso, mentre si desidera conservarlo.
Supponendo di aver salvato questo programma in un file di nome wordfreq.awk, e che i dati siano in file1, il seguente comando con pipeline:
awk -f wordfreq.awk file1 | sort -k 2nr
produce una tabella delle parole che appaiono in file1 in ordine descrescente di frequenza.
Il programma awk
da solo gestisce adeguatamente i dati e produce
una tabella delle frequenza che non è ordinata.
L’output di awk
è poi messo in ordine dal programma di utilità
sort
e stampato sullo schermo.
Le opzioni passate a sort
richiedono un ordinamento che usi come chiave il secondo campo di ogni riga
in input (saltando il primo campo), che le chiavi di ordinamento siano
trattate come quantità numeriche
(altrimenti ‘15’ sarebbe stampato prima di ‘5’), e che l’ordinamento
sia fatto in ordine decrescente (inverso).
Il comando sort
potrebbe anche essere richiamato dall’interno del
programma, cambiando l’azione da fare nella regola END
a:
END { sort = "sort -k 2nr" for (word in freq) printf "%s\t%d\n", word, freq[word] | sort close(sort) }
Questa maniera di ordinare dev’essere usata su sistemi che non hanno delle
vere e proprie pipe a livello di riga di comando (o di procedura di
comandi).
Si veda la documentazione generale riguardo al sistema operativo per maggiori
informazioni su come usare il programma sort
.
Successivo: Programma riordino diario, Precedente: Programma labels, Su: Programmi vari [Contenuti][Indice]