domenica 4 marzo 2012

Un po' di AWK. Seconda parte.

Salve!

Questa seconda parte, a dire il vero, c'entra poco con la prima (qui).

Spero di rifarmi con la terza parte. Tempo al tempo.

Oggi (cioè ieri) mi sono lasciato prendere un pò la mano.

Sarà perchè ho creato uno script AWK per il vicino, prossimo alla laurea, affinchè calcolasse la media dei suoi voti.

Ecco, condivido con voi una delle mie esercitazioni notturne con AWK.

Roba di poca cosa, chiaro! Ancora sono agli esordi. Qualora riscontraste delle anomalie nel prosieguo del post, non esitate a farmelo presente. :)

Anzitutto ho creato la seguente tabella, un file di testo:

Alunno1 22 25 18 27 19
Alunno2 18 18 18 17 17
Alunno3 23 22 25 29 29
Alunno4 24 24 25 24 24
Alunno5 30 29 30 29 29
Alunno6 18 17 17 17 19
Alunno7 29 30 30 30 30
Alunno8 24 25 19 30 30
Alunno9 23 30 17 26 25


Ho elencato nove alunni. Accanto a ognuno di loro ci sono 5 numeri; ogni numero rappresenta un voto per una determinata prova (esame).

Per intenderci, il primo alunno (alunno1) ha ottenuto 22 alla prima prova, 25 alla seconda, 18 alla terza, 17 alla quarta, 19 alla quinta. Discorso analogo per gli alunni successivi.

Ora il problema che mi sono posto è questo:

Riuscire a creare uno script che mi permetta di calcolare la media dei voti per ciascuno alunno e dica chi è stato promosso e chi respinto.

Esercizio per principianti, lo so. :)) Intanto da qualche parte bisogna pur cominciare...

Va bene. Ho salvato la tabella nella directory Documenti e nominata "tabella.txt"

Poi, pian piano, ho costruito lo script.

Eccolo:

#!/usr/bin/awk -f
#calcolare la media dei voti con relativi giudizi.
BEGIN {
              print "     \fESITO DELLE PROVE\n"
              print " \fNome\tMedia\tGiudizio\n";
}

{
    totale=$2+$3+$4+$5+$6;
    media=totale/5
    if (media >= 18) {giudizio="promosso";}
    else if (media<18) {giudizio="respinto";}
    print $1,media,"=>",giudizio;
}

END {
          print "------------------------"
}



C'è poco da dire (o forse no)!

Solo che ora è troppo tardi....

Tralascio BEGIN E END, ne parleremo una prossima volta; mi soffermo, invece, sulla parte centrale dello script.

Anziutto ho impostato la somma di tutti i voti per ciascuno alunno (totale=$2+$3+$4+$5+$6).

Ok, prendiamo la prima riga della tabella: Alunno1 22 25 18 27 19.

Questa riga, detta record, è divisa in tanti campi. Ogni campo è una stringa (o numero) separata da spazi (non sempre è così). Il primo campo corrisponde a "Alunno1", e viene chiamato $1; il secondo campo corrisponde al numero 22, ed è chiamato $2; il terzo campo corrisponde al numero 25, ed è chiamato $3, e via dicendo.

Dunque, quando scrivo "totale=$2+$3+$4+$5+$6", non faccio altro che dire a AWK di sommare il secondo campo, il terzo, il quarto, il quinto e il sesto. Ne resta fuori il primo, perchè non è un voto (Alunno1). Badate, la somma non riguarderà solo i campi della prima riga, ma anche i successivi. 

Poi ho impostato la formula della media. Qui c'è poco da dire.

Ed eccoci al costrutto if else-if. Diciamola così: Se la media è superiore a 18, inserisci nella variabile-contenitore "giudizio" il contenuto "promosso"; se invece la media è inferiore a 18, inserisci il contenuto "respinto"

Infine c'è print, che stampa l'elenco degli alunni con le rispettive medie e i relativi giudizi (promosso/respinto).

Dimenticavo, tutto questo corpo di codice deve essere racchiuso tra parentesi graffe.

Dopo aver salvato la tabella nella cartella Documenti, la stessa cosa dobbiamo fare per lo script che nomineremo "media.awk"

Aperto un terminale, spostiamoci nella cartella Documenti:

$ cd Documenti

Assegnamo allo script i permessi di esecuzione

$ chmod +x media.awk

ed eseguiamolo

$ ./media.awk tabella.txt

Ecco l'output:

Non fate caso alla media dell'alunno7!!! Piccolo errore :D
  
Si può fare di meglio? Boh! (sicuramente!) :))

Ciao!

2 commenti:

  1. Ciao Bit3Lux, sono tornato a studiarmi lo scripting di shell.
    Molto interessante awk, inoltre spiegato così bene sembrerebbe davvero facile, aspetto la 6° puntata.
    Spero non ti offenderai se mi permetto di indicare qualche considerazione generale.
    È buona norma usare nomi, dei file dati e dei file di programma, esplicativi; aiuta molto utilizzare questo metodo, deve diventare automatico, (il discorso vale anche per i nomi delle variabili). Per esempio invece di un generico tabella.txt sarebbe meglio qualcosa del tipo voti_alunni.txt, di conseguenza darei allo script un nome del tipo elabora_voti.awc; se la directory in cui sono i file fosse affollata di file dati e file di script risulterebbe molto più facile collegare gli script ai dati corrispondenti.

    Altra cosa riguarda il discorso if...elseif...else: se le condizioni da verificare sono solo due conviene usare if...else senza elseif.
    Inoltre nel tuo script non viene considerata la media uguale a 18 in questo caso l'alunno risulterebbe respinto, invece fortunatamente con 18 si è promossi :-)

    Io utilizzerei:


    if (media>=18) {giudizio="promosso";}
    else {giudizio="respinto";}
    print $1,media,"=>",giudizio;


    Vale anche per la terza parte di "Un pò di AWK"

    Continua così che ti seguo.

    Ciao

    RispondiElimina
  2. Ciao Giovanni! Scusami se ti rispondo dopo sette mesi...Ho corretto lo script, grazie...E grazie per gli altri consigli. :)

    RispondiElimina