AWK è un linguaggio di programmazione che esegue azioni definibili sulla base del matching di pattern definibili.
Il suo input (un file o lo standard output di un comando) viene processato una riga alla volta e se la riga soddisfa il pattern specificato, AWK esegue l'azione specificato, scrivendo su standard output il risultato di questa azione.
E' comune in tutti gli Unix, su Linux si trova l'implementazione GNU, chiamata con la solita fantasia gawk e, come spesso accade, con una serie di funzionalità aggiunte.
In questo contesto ci limiteremo a fare alcuni esempi che possono dare un'idea delle potenzialità di awk, della logica del suo funzionamento e della sua estrema utilità in molte attività di system administration.
Le regole che awk deve seguire possono essere scritte in un file o direttamente inserite fra apici negli argomenti del comando:
awk -f file_delle_regole file_di_testo_da_processare
è analogo a:
awk 'regole' file_di_testo_da_processare
ed etrambi sono analoghi a:
cat file_di_testo_da_processare | awk -f file_delle_regole
Le regole hanno di base un formato tipo:
pattern { azione }
dove pattern indica il matchind secondo criteri vari e l'azione quello che awk genera sullo standard output per ogni riga di testo nello standard input che soddisfa il pattern stabilito.
Vediamo alcuni esempi pratici, che possono chiarire molto meglio ed iniziare ad aprirci gli occhi sul versatile mondo di awk.
Visualizzo l'output di un normale comando (ma si possono immagina le variazioni sul tema):
ls -l
total 304
-rw-r--r-- 1 root root 11142 Aug 23 18:36 config.ini
drwxr-xr-x 2 shiva shiva 4096 Sep 3 22:25 docs/
-rw-r--r-- 1 root root 2807 Aug 23 16:49 installer.ini
-rw-r--r-- 1 root root 23264 Aug 23 16:49 license.txt
-rwxr-xr-x 1 root root 1449 Aug 23 16:49 netscape-installer*
-rwxr-xr-x 1 root root 249564 Aug 23 16:49 netscape-installer-bin*
-rw-r--r-- 1 root root 7995 Aug 23 16:49 README
Redireziono l'output del comando allo stdin di awk:
ls -l | awk '{print $1}'
total
-rw-r--r--
drwxr-xr-x
-rw-r--r--
-rw-r--r--
-rwxr-xr-x
-rwxr-xr-x
-rw-r--r--
Qui non viene specificata nessuna regola di matching e per tutte le righe di input awk stampa il primo campo ($1) Di default awk considera lo spazio come carattere di separazione fra i campi di una riga e non fa distinzione (ovviamente) fra righe con sintassi, significato e formato diversi (la prima rispetto a tutte le altre).
Per stampare il nono campo di ogni riga basta sostituire $1 con $9:
ls -l | awk '{print $9}'
config.ini
docs/
installer.ini
license.txt
netscape-installer*
netscape-installer-bin*
README
Se il nono campo non esiste, non viene stampato (della prima riga dell'ls -l originario non c'è più traccia).
Per stampare l'intera riga e non solo alcuni campi uso $0.
E se voglio iniziare a introdurre qualche regola di matching uso una simile sintassi:
ls -l | awk '$3 == "root" {print $0}'
-rw-r--r-- 1 root root 11142 Aug 23 18:36 config.ini
-rw-r--r-- 1 root root 2807 Aug 23 16:49 installer.ini
-rw-r--r-- 1 root root 23264 Aug 23 16:49 license.txt
-rwxr-xr-x 1 root root 1449 Aug 23 16:49 netscape-installer*
-rwxr-xr-x 1 root root 249564 Aug 23 16:49 netscape-installer-bin*
-rw-r--r-- 1 root root 7995 Aug 23 16:49 README
In questo caso il pattern matching è piuttosto semplice: eseguo l'azione fra parentesi graffe solo per le righe in cui il terzo campo coincide con la stringa "root".
L'output di awk può essere opportunamente editato e, ovviamente, redirezionato all'input di altri comandi:
ls -l | awk '$3 == "shiva" {print "rm -Rf " $9}' | sh
Qui, su stdout non compare nulla, ma come ci si può immaginare la directory docs/, con owner shiva, è stata rimossa. Notare che awk permette di stampare stringhe arbitrarie nelle sue azioni. Notare che lo spazio, all'interno dei doppi apici, dopo rm -Rf è necessario.
Questo è solo l'inizio, AWK è un vero e proprio linguaggio di programmazione interpretato, che presenta direttive BEGIN-END (vengono eseguite solo prima e dopo il processing dell'input), cicli IF-ELSE, variabili speciali, numerose variazioni e metodi per il matching di pattern (amggiore, minore, diverso, ecc), funzioni varie ecc.
E' molto utile per ripetere automaticamente operazioni simili secondo criteri predefinibili: di fatto esattamente quello che un sysadmin ama fare: automatizzare compiti noiosi ed evitare di digitare le quasi stesse cose per più di 3 volte di seguito.
Ricerca nel file system: find, locate. Confronto e verifica di file: diff, md5sum. Filtri di output: grep, wc, sed, awk.