giovedì 10 gennaio 2013

Un po' di AWK. Sedicesima parte.

In questo post continuiamo a parlare di arrays.

Ci serve gawk. Su debian non era installato

$ sudo apt-get install gawk

Gawk è l'implementazione del progetto GNU del linguaggio di programmazione
AWK. Gawk è basata sulla descrizione contenuta in The AWK Programming Language, di Aho, Kernighan e Weinberger cui però sono state aggiunte ulteriori funzionalità.

Una cosa alla volta. Le vedremo tutte 'ste funzionalità eh! Ancora siamo solo all'inizio del sequel "Un po' di AWK". Mancheranno una novantina di post per finire... :D

Va bene, oggi parleremo di ordinamento. Ordinamento di un array in base agli indici o ai suoi valori. Perciò affronteremo le funzioni asort() e asorti() e altre cose sfiziose...

In AWK gli arrays sono solo di tipo associativo, cioè gli indici possono essere non numerici, bensì stringhe. Alla fine, credetemi, AWk li vedrà solo ed esclusivamente come stringhe. C'è da dire inoltre che nell'uso tipico degli arrays associativi non è necessario alcun ordinamento, ma noi andiamo oltre. Non ci possiamo mica accontentare della tipicità dell'uso.

Asort() ordina un array in base a suoi valori e asorti() li ordina in base alle chiavi (termine che preferisco) o indici.

Mi rendo conto che è più utile mostrare esempi che esporre teoria.

Primo script. (es.awk)
#!/usr/bin/awk -f

BEGIN {
    print "\n\t.............START....................\n"
    FORMAT="\t%-14s%s\n"
    printf FORMAT,"SQUADRA","NOME STADIO"
    print ""
    squadra["Inter"]="Giuseppe Meazza";
    squadra["Juve"]="Stadio Olimpico";
    squadra["Chievo"]="Marcantonio Bentegodi";
    squadra["Palermo"]="Renzo Barbera";
    squadra["Genoa"]="Luigi Ferraris";
    squadra["Bologna"]="Renato Dall'Ara";
    squadra["Napoli"]="San Paolo";
    squadra["Cagliari"]="Sant'Elia";

    print "\nAsort: Ordinamento in base ai valori\n"
    A = asort(squadra,alta);
    for (i=1; i<= A; i++) {
             printf FORMAT,i,alta[i]; 
    }

    print "\nAsorti: Ordinamento in base agli indici\n"
    A = asorti(squadra,bassa);
    for (i=1; i<= A; i++) {
             printf FORMAT,bassa[i],i;
    }

    print "\nIndici e valori dell'array Squadra sono rimasti intatti\n"
    for (i in squadra){
             printf FORMAT,i,squadra[i]
    }

    print "\n\t.................END..................\n"
 }
In questo script anzitutto ho creato l'array squadra che contiene come indici varie squadre. E in corrispondenza di una determinata squadra (indice) ho assegnato come valore il relativo stadio. Chissà se gli stadi corrispondono. Sono anni che non seguo il calcio...

Poi ho creato la variabile A e gli ho assegnato come valore la funzione asort()

    A = asort(squadra,alta);
    for (i=1; i<= A; i++) {
               printf FORMAT,i,alta[i];

    }

Una cosa di notevole rilevanza è che tra le parentesi tonde troviamo due nomi. Il nome dell'array, squadra appunto, e un altro nome, che è di fantasia. Perchè questa scelta? La funzione asort ordina l'array in base ai suoi valori, cioè, nel nostro caso, mette gli stadi in ordine alfabetico, ma nello stesso tempo distrugge irreversibilmnente gli indici originali. Per evitare questo problemo faccio uso di un secondo argomento (opzionale). Per farla breve, il nome di fantasia è un array in cui viene copiata la matrice originale (indici e relativi valori). L'array originale (l'array squadra) invece resterà intatto. Infatti potrà essere richiamato nel prosieguo di uno script.

A questo punto avrei potuto creare un nuovo script. Invece no. Questo perchè a me premeva far vedere in un unico script la differenza tra le due funzioni: asort() e asorti()

    A = asorti(squadra,bassa);
    for (i=1; i<= A; i++) {
               printf FORMAT,bassa[i],i;

   }

La funzione asorti() ordina l'array in base ai suoi indici, cioè, nel nostro caso, mette i nomi delle squadre in ordine alfabetico. Il problema della funzione asorti() è che distrugge i valori corrispondenti. Ecco perchè, anche in questo caso, faccio uso di un secondo argomento. Il discorso è analogo a quello della funzione asort(), perciò non mi dilungo.

Per finire la prova del nove!

    for (i in squadra){
           printf FORMAT,i,squadra[i]


Questa terza parte dello script è la prova che l'array originale, squadra appunto, non è stato intaccato minimimente dalle funzioni usate.

Passiamo all'altro script. A mio parere molto più interessante del primo. (es1.awk)
#!/usr/bin/awk -f

BEGIN {
    print "\n\t.............START....................\n"
    FORMAT="\t%-14s%s\n"
    printf FORMAT,"SQUADRA","NOME STADIO"
    print ""
    squadra["Inter"]="Giuseppe Meazza";
    squadra["Juve"]="Stadio Olimpico";
    squadra["Chievo"]="Marcantonio Bentegodi";
    squadra["Palermo"]="Renzo Barbera";
    squadra["Genoa"]="Luigi Ferraris";
    squadra["Bologna"]="Renato Dall'Ara";
    squadra["Napoli"]="San Paolo";
    squadra["Cagliari"]="Sant'Elia";

    print "\nOrdinamento in base agli indici\n"
    PROCINFO["sorted_in"] = "@ind_num_asc" 
    for (i in squadra){
           printf FORMAT,i,squadra[i] 
    }

    print "\nOrdinamento in base ai valori\n"
    PROCINFO["sorted_in"] = "@val_type_asc"
    for (i in squadra){
           printf FORMAT,i,squadra[i]
    }
    print "\n\t.................END..................\n"
}
Le seguenti righe di codice ordinano l'array in base ai suoi indici:

PROCINFO["sorted_in"] = "@ind_num_asc"
    for (i in squadra){
           printf FORMAT,i,squadra[i]

    }

Queste altre invece lo ordinano in base ai suoi valori:

PROCINFO["sorted_in"] = "@val_type_asc"
    for (i in squadra){
           printf FORMAT,i,squadra[i]

    }

Per il momento non aggiungo altro. Nel prossimo post parlerò approfonditamente di questo secondo script. Se inizio ora, non finisco più...ed è già l'una di notte.

L'indice del sequel "Un po' di AWK" qui.
L'indice di "Breve Esercizi" qui

Alla prossima!

Nessun commento:

Posta un commento