Introduzione a AWK: Tutorial

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.

Privacy Policy