Awk, o meglio la sua moderna implementazione Gawk, può essere definito come un linguaggio di scripting per l’elaborazione dei dati nei file di testo. L’accostamento a grep è lecito, ma awk, risulta più flessibile, potente e inevitabilmente maggiormente complesso.
Qui di seguito elencherò alcune porzioni di codice, introducendo un commento per illustrare la potenza di awk:
who | awk '{print $1, $4, $3}'
L’istruzione who visualizza gli utenti loggati, mentre il carattere pipe concatena l’istruzione con awk. che si limita a stampare a video il primo argomento, poi il quarto e quindi il terzo dell’output prodotto da who.
L’ istruzione awk è composta sempre da due parti:
- la prima parte (opzionale) è un pattern da verificare. Se la verifica ha esito positivo, allora i risultati vengono processati.
- la seconda parte è racchiusa tra parentesi graffe e individua l’operazione da compiere.
Nel’istruzione precedente non esiste alcun pattern da verificare, quindi verranno stampati il primo, il quarto e il terzo argomento dei risultati dati dall’istruzione who.
Altre informazioni basilari nell’apprendimento di awk, sono le seguenti:
- l’argomento
$0
indica l’intero record. Quindi senza specificare un pattern di verifica, awk risulta molto simile a grep. - l’input elaborato da awk è una singola linea. Quindi a meno di specificare un carattere di separazione, per awk un record è dato da una linea.
Specificare il carattere di separazione
awk -F, '{print $1}' nomefile
Questa istruzione specifica il carattere di separazione di record con l’opzione -F seguito dal carattere (nel nostro caso, la virgola). Segue poi il campo da stampare (il primo) e il nome del file
Pattern di ricerca
ls -l | awk '$3 !~ /^root$/ {print $9, $1}'
In questo caso viene verificato un preciso pattern: viene analizzato il terzo campo di ogni riga ($3) e confrontato con il pattern root (si vedano le regex). Solo gli argomenti diversi da root verranno considerati corretti. Di questi si stamperà il nono e il primo campo.
Azione composte
awk '{out = ""; for (i = 1; i <= NF; i += 1) out = out $i "* "; print out }'
Quest’ultimo comanda aggiunge alcuni aspetti importanti:
- Il punto e virgola (;) permette di separa varie istruzioni consecutive, permettendo di realizzare costrutti più complessi
- NF individua il numero di campi in un record
In definitiva questo comando:
- definisce una variabile out
- un ciclo viene incrementato di 1 sino a quando non si raggiunge il numero di campi contenuti in un record
- si assegna alla variabile out il suo valore concatenato con il carattere *
- infine lo si stampa con il comando print
Awk è un tool estremamente complesso e duttile, e non sempre i suoi vantaggi sono tali da preferirlo a grep o cut.
cat nomefile | cut -d, -f 3-2-1
Con cat viene letto un file e l’output reindirizzato su cut (che stampa alcune parti di una riga).
- il delimitatore dei campi viene impostato con -d (nel nostro caso è la virgola)
- i campi da stampare vengono indicati facendoli precedere da -f