domenica 23 dicembre 2012

Brevi Esercizi #11. Sommare i numeri in colonne e righe con AWK.

Salve!

Il quesito di oggi.
Ho una tabella di numeri. Voglio sommare i numeri di ciascuna colonna e ciascuna riga e ottenerne il totale per colonne e per righe. 

La tabella (tabella1.txt).

508+133+900 
981+240+325 
450+340+435 
111+234+556
768+998+431
901+123+877
213+356+678
321+653+876
Lo script (somma.awk).
#!/usr/bin/awk -f
 
  BEGIN { 
         print "\n\t\t_____SOMMA_____\n";
         FS="+"; OFS = "\t";
  }                                                   
    { 
      a += $1; b += $2; c += $3;
      tot = ($1+$2+$3); 
      print "\t" $1,$2,$3,"|  "tot;
    }
  END { 
       print "\t________________________________\n";
       print "\t" a, b, c, "--> "(a+b+c)" (Totale)","\n";
 }
In genere, ma non necessariamente, uno script in awk consta di tre parti. Nella prima parte, BEGIN, vengono eseguite alcune operazioni prima che il file di testo venga processato. Si inizializzano variabili, si provvede alla formattazione del testo, etc. Ciò non toglie che in questa sezione possano essere compiute anche operazioni più complesse. Nel mio caso, ad esempio, faccio scrivere la parola "SOMMA" nella tabella in output utilizzando "\n" per andare a capo o "\t" per centrare la scritta.  Poi, sempre nella prima sezione, setto le variabili FS, separatore di campo in entrata, e OFS, separatore di campo in uscita. Di queste cose ne abbiamo ampiamente parlato nel sequel "Un po' di AWK" il cui indice lo trovate qui.
Nella parte centrale dello script abbiamo la sezione delle azioni. Azioni che vengono eseguite mentre il testo viene processato da awk. Se scrivo "a +=  $1" non faccio altro che dire ad awk di assegnare la somma della prima colonna di numeri alla variabile a. Lo stesso discorso vale per "b += $2" e "c += $3". Alla fine mi trovo con tre variabili, a b c, contenenti ciascuna la somma dei numeri delle rispettive colonne.  Alla variabile tot assegno la somma dei numeri di ciascuna riga. Già con queste semplicissime azioni, abbiamo fatto svolgere ad awk il lavoro più duro. Ora si tratta di stampare il contenuto delle variabili. Poi abbiamo la terza sezione, END. Qui vengono compiute operazioni  dopo che il file di testo sia stato processato. Anche qui, come in BEGIN, possono essere compiute operazioni alquanto complessse. Nel mio caso, faccio qualche altro piccolo ritocco alla tabella in output e poi faccio stampare il contenuto delle variabili a b e c. Ve le ricordate? :)

Alla fine ottengo questo risultato.
Vi ricordo che l'indice di "Brevi Esercizi" lo trovate qui.

Alla prossima!

5 commenti:

  1. Ottimissimo; il passo successivo sarebbe di usare printf per avere un allineamento a destra come siamo abituati.
    Ottima idea averlo lasciato come esercizio per i lettori ;-)

    RispondiElimina
  2. Si, hai ragione, avrei dovuto usare printf. Ecco lo si lascia come esercizio ai lettori...printf + format eh! :D

    RispondiElimina
  3. Salve, come posso fare una somma per righe senza tenere conto di elementi nulli?? Cioè nel caso avessi un file .txt del tipo:

    23 21 0
    45 0 0
    43 45 2
    56 76 4
    22 89 8

    RispondiElimina
    Risposte
    1. Devi usare lo stesso script che trovi nel post. Tuttavia, dato che i campi sono divisi da spazi e non dal segno +, devi togliere dallo script "FS="+";", che si trova dentro BEGIN.
      Da così:
      FS="+"; OFS = "\t";
      a così:
      OFS = "\t";

      Elimina
  4. se ho tre colonne di numeri sia negativi che positivi, come faccio a sommare solo i numeri negativi, escludendo le intere colonne se non contengono i numeri negativi?
    Grazie

    RispondiElimina