venerdì 23 marzo 2012

Un po' di AWK. Quinta parte.

Salve!

Continuo con le mie esercitazioni pubbliche su AWK.

Poteva mancare che AWK non avesse le sue variabili Speciali? Certo che no! C'è chi preferisce chiamarle variabili Built-in...Alla fine si chiamano proprio così. Si tratta infatti di variabili il cui valore è predefinito. Ne abbiamo già parlato, ma l'argomento merita rispetto perciò continueremo a parlarne a lungo. :D

Nell'ultimo post abbiamo visto (oggi uso la prima persona plurale) la variabile FS. Ecco, oggi continuerò a parlare di FS (come promesso!).

FS, che sta per Field Separator, serve a definire il codice da prendere in considerazione per separare i record in campi. Giusto per dare una spolverata ai ricordi, i record sono le linee di una tabella; i campi, invece, sono le stringhe (parole, numero o altro) in cui i record si dividono. Una particolarità di tutte le variabili speciali di AWK, quindi anche di FS, è che sono scritte in lettere maiuscole. Della variabile FS abbiamo già fatto degli esempi. Vedremo anche dei casi limiti, cioè dei casi che praticamente non si presenteranno (quasi) mai ma, come diceva la "buonanima" del mio professore di procedura penale: La realtà supera di gran lunga la fantasia.

Facciamo qualche altro esempio:

$ echo "cane,gatto;topo.elefante" | awk -F "[,;.]" '{print $4}'
elefante
$ echo "cane,gatto;topo.elefante" | awk -F "[,;.]" '{print $3}'
topo
$ echo "cane,gatto;topo.elefante" | awk -F "[,;.]" '{print $2}'
gatto
$ echo "cane,gatto;topo.elefante" | awk -F "[,;.]" '{print $1}'
cane
$ echo "cane,gatto;topo.elefante" | awk -F "[,;.]" '{print $1,$2,$3}'
cane gatto topo

Come si può notare, a FS ho assegnato come valore la virgola, il punto e virgola e il punto. Così l'unico record sarà diviso in quattro campi.

Se però assegno ad FS solo la virgola come valore, si verificherà qualcosa del genere:

$ echo "cane,gatto;topo.elefante" | awk -F "," '{print $2}'
gatto;topo.elefante

Cioè il record sarà diviso in solo due campi: cane da una parte e la "triade" che è stata stampata, dall'altra.

Può verificarsi un'altra situazione.

lupo:gatto:pecora:toro
lupo,gatto,pecora,toro
lupo gatto pecora toro
lupo:gatto:pecora:toro
lupo,gatto,pecora,toro
lupo gatto pecora toro


Nel primo record le parole sono divise dai due punti; nel secondo, da una virgola;nel terzo, da uno spazio;  e via dicendo...

Come ci regoliamo in un caso del genere? Cioè come dovremo settare la nostra variabile FS affichè awk processi tutti i record?

Qui ci scappa lo script, che però spiegheremo in un altro post. Lo script serve a dimostrare come si può cambiare il valore della variabile FS in modo dinamico!

Anzitutto salviamo la tabella nella cartella Documenti e nominiamola "animali.txt"

Lo script è il seguente:

#!/usr/bin/awk -f
{
       if ( $0 ~ /:/ ) {
        FS=":";
    } else if ($0~/,/) {
        FS=",";
    } else {
        FS=" ";
    }
    $0=$0
    print $2,$3
}


Dopo aver salvato il file animali.txt nella cartella Documenti, la stessa cosa dobbiamo fare per lo script, che nomineremo "prova.awk"

Aperto un terminale, spostiamoci nella cartella Documenti:

$ cd Documenti

Assegnamo allo script i permessi di esecuzione

$ chmod +x prova.awk

ed eseguiamolo

$ ./prova.awk animali.txt

Output:

Gli ho chiesto di stampare solo i campi $2 e $3
Se gli avessi chiesto di stampare i campi  $1,$2,$4, avremmo avuto:


La prossima volta parleremo di RS (separatore di record).

Ciao :))

4 commenti: