Home Mappa Indice Ricerca Notizie Archivio Link A proposito di LF
[Barra Superiore]
[Barra Inferiore]
[Photo of the Author]
di Javier Palacios Bermejo

L´autore:

Javier è impegnato in un Ph. D. in astronomia in un'Università spagnola, dove amministra un gruppo di workstation. Il lavoro giornaliero nel suo dipartimento viene svolto su macchine Unix. Dopo qualche prova e qualche problema iniziale la scelta è ricaduta su slackware Linux. Linux si è rivelato essere molto meglio di altri sistemi Unix proprietari.

Contenuto:

Esempi con AWK: una breve introduzione

[Ilustration]

Sommario:

Questo articolo mostra qualcuno dei trucchi che si possono realizzare con AWK. Non è un tutorial ma fornisce alcuni esempi di uso comune.



Originariamente, l'idea di scrivere questo testo mi è venuta dopo aver letto un paio di articoli pubblicati su LinuxFocus e scritti da Guido Socher. Uno di essi, su find e i comandi correlati, mi ha fatto realizzare che non ero l'unico ad usare la linea di comando. Spesso interfacce grafiche carine non mostrano come vengono fatte realmente le cose (quella è la direzione in cui Windows è andato anni fa). L'altro articolo parlava delle espressioni regolari. Sebbene le espressioni regolari siano solo appena trattate in questo articolo, è utile conoscerle per ottenere il massimo da awk e da altri comandi come sed e grep.

La questione chiave è se questo comando awk sia veramente utile. La risposta è si, eccome! Potrebbe essere utile per un utente normale manipolare file di testo, riformattarli, ecc... Per un amministratore di sistema AWK è veramente una utility importantissima. Provate a guardare in /var/yp/Makefile o osservate gli script di inizializzazione. AWK viene usato ovunque.  

Introduzione ad awk

Le mie prime esperienze con AWK risalgono a molto tempo fa. Avevo un collega al quale serviva di elaborare alcuni output veramente grossi di un piccolo Cray. Il manuale di awk sul Cray era veramente piccola, ma lui disse che AWK sembrava molto ciò di cui avevabisogno sebbene ancora non capisse come usarlo.
Molto tempo dopo (parlo di nuovo della mia vita) un commento casuale in un altroposto, un altro collega usava AWK per estrarre la prima colonna da una tabella:

awk '  '{print $1}'   file


Facile, vero? Questa semplice operazione non richiede alcuna programmazione complessa in C né in qualche altro linguaggio compilato o interpretato. E' sufficiente un'unica linea di AWK.

Imparata la lezione di estrazione di una colonna possiamo fare cose come rinominare file:
ls -1 pattern | awk '{print "mv "$1" "$1".new"}' | sh

... e altro. Usando sed oppure grep insieme all'esempio precedente otteniamo un tool ancora più potente.

  1. rinominazione dentro il nome
    ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
    (benché in alcuni casi non funziona, come in file_old_and_old)

  2. rimozione dei soli file (si può fare usando solo rm, ma che dire di un alias come 'rm -r')
    ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
    (analogamente potrebbe non funzionare con strani nomi o permessi di accesso). Attenzione quando provate questo comando nella vostra home directory: rimuoviamo dei file!

  3. rimozione delle sole directory
    ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
    (Credo che questo funzioni in ogni caso, e possiamo migliorarlo usando ls -p | grep /$ | wk '{print "rm -r "$1}')
    Attenzione quando provate questo comando nella vostra home directory: rimuoviamo dei file!

Come si può vedere, AWK è veramente utile quando le stesse operazioni sono ripetute ad oltranza... e, comunque, è molto più divertente scrivere un programma in AWK che ripetere quasi le stesse cose 20 volte manualmente.

In realtà, sebbene useremo il nome comando awk, awk non è il tipo di cosa che viene di solito chiamato comando. awk è un linguaggio di programmazione, con una sintassi per molti versi simile a quella del C. E' un linguaggio interpretato e l'iterprete awk esegue le istruzioni.

Per quanto riguarda la sintassi del comando stesso:

# gawk --help
Usage: gawk [POSIX or GNU style options] -f progfile [--] file ...
        gawk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:          GNU long options:
        -f progfile             --file=progfile
        -F fs                   --field-separator=fs
        -v var=val              --assign=var=val
        -m[fr] val
        -W compat               --compat
        -W copyleft             --copyleft
        -W copyright            --copyright
        -W help                 --help
        -W lint                 --lint
        -W lint-old             --lint-old
        -W posix                --posix
        -W re-interval          --re-interval
        -W source=program-text  --source=program-text
        -W traditional          --traditional
        -W usage                --usage
        -W version              --version

Report bugs to bug-gnu-utils@prep.ai.mit.edu,
with a Cc: to arnold@gnu.ai.mit.edu
Invece di virgolettare (') il programma nella linea di comando, è possibile scriverlo in un file, e richiamarlo con l'opzione -f, e con variabili definite nella linea di comando, usando -v var=val è possibile aggiungere un minimo di versatilità ai programmi che scriviamo.

Awk è, impropriamente parlando, un linguaggio orientato alla gestione delle tabelle. Ovvero, di informazioni che possono essere raggruppate in campi e record. Il vantaggio è che la definizione del record (nonché quella del campo) è estremamente flessibile.

Awk è potente. E' stato ideato per trattare record di una linea, ma questo punto potrebbe essere rilassato. Per renderci conto di alcuni di questi aspetti, daremo un'occhiata ad alcuni esempi illustrativi (e reali).

Programmi come questi richiedono solo 5 minuti di progetto e altri 5 per la scrittura (o più di 20 minuti sensa pensare, provando un po', nel modo più buffo).

Ho usato awk per molti altri compiti (generazione automatica di pagine web con informazioni prese da semplici database) e ne so abbastanza di programmazione con awk da essere sicuro che si possono fare molte cose.
Basta fare volare la tua immaginazione.

 

Un problema

 

(e una soluzione)

Un problema è che awk ha bisogno di informazioni perfettamente tabellari, senza buchi, awk cioè non funziona con colonne di dimensione fissa. Questo non è un problema se ci creiamo da soli l'input di awk: scegliamo qualcosa di poco comune per separare i campi, e successivamente aggiustiamo le cose con FS ed è fatta!!! Se abbiamo già l'input potrebbe essere più problematico, in quanto il carattere di separazione dei campi (FS) può essere uno spazio, nel qual caso alcuni nomi composti possono essere in problema. Per esempio una tabella come questa:
1234  HD 13324  22:40:54 ....
1235  HD12223   22:43:12 ....
è difficile da trattare con awk. Talvolta input così fatti sono inevitabili. Inoltre, questo è molto comune poiché l'ingresso dei dati è per lo più non omogeneo. Se abbiamo solo una colonna con questa caratteristica, il problema è risolvibile (e se qualcuno sa come trattare più di una colonna in generale, è pregato di farmelo sapere!).
Una volta dovetti affrontare una tabella simile a quella su descritta. La seconda colonna era un nome e includeva un numero variabile di spazi. Come succede di solito, dovetti ordinarla usando una colonna dopo questa colonna con spazi aggiuntivi. Ho provato più volte con sort +/-n.m che aveva lo stessa problema degli spazi.
Improvvisamente realizzai che la colonna che volevo ordinare era l'ultima e che awk sa quanti campi ci sono nel registro corrente. Pertanto era sufficiente accedere all'ultimo campo (talvolta $9, e talvolta $11, ma sempre NF). Alla fine della giornata il risultato desiderato era ottenuto:
{
  printf $NF
  $NF = ""
  printf " "$0"\n"
}

Questo mi da un output uguale all'input, ma con l'ultima colonna traslata in prima posizione. Ovviamente, questo metodo si adatta facilmente al caso del terzo campo a cominciare dalla fine, o al caso del campo che viene dopo un campo di controllo avente sempre lo stesso valore.
Con l'ultima colonna spostata in prima posizione possiamo ordinare i dati con un semplice sort.
Basta usare le idee e l'immaginazione.

 

Addentrandosi in AWK

 

Lavorare su parti delle linee

Fino ad ora, quasi tutti gli esempi elaborano tutte le linee del file in ingresso. Ma, come sostiene anche la pagina del manuale, è possibile elaborare solo alcunde delle linee in ingresso. E' sufficiente far precedere al gruppo di comandi la condizione che la linea deve soddisfare. Tale condizione può essere molto flessibile, da una espressione regolare fino a un controllo sul contenuto di qualche campo, con anche la possibilità di raggruppare le condizioni con gli appropriati operatori logici.

 

Awk come linguaggio di programmazione

Come qualsiasi altro linguaggio di programmazione, awk implementa tutte le necessarie strutture per il controllo del flusso, nonché un insieme di operatori e funzioni predefinite per manipolare numeri e stringhe. La sintassi è simila a quella del C.

Ed è possibile, naturalmente, includere funzioni definite dall'utente con la parola chiave function, e scrivere i comandi associati come se stessimo elaborando una linea di un file di ingresso. Oltre alle comuni variabili scalari, awk è anche in grado di gestire array di dimensioni variabili.

 

Inclusione di librerie

Come succede in tutti i linguaggi di programmazione, ci sono delle funzioni molto comuni e diventa scomodo dover importare pezzi di codice con il taglia e incolla. Per questo motivo esistono le librerie. Con la versione della GNU di awk, è possibile includerle nei programmi awk. Non approfondiremo ulteriormente questo aspetto di awk poiché è al di là degli scopi di questo articolo.

 

Conclusioni

Certamente, awk potrebbe non essere potente come molti altri tool ideati con obiettivi analoghi, ma ha il grande vantaggio che è possibile scrivere in pochissimo tempo piccoli programmi perfettamente adattati alle proprie necessità.

AWK è l'ideale per le finalità per le quali è stato scritto: leggere dati una linea alla volta e operare sulle stringhe e sui pattern nelle linee.

File come /etc/password sono perfettamente riformattabili e modificabili con AWK. AWK è insostituibile per questi compiti.

Naturalmente AWK non è l'unica alternativa. Perl è un forte competitore ma vale ancora la pena di conoscere qualche trucco con AWK.

 

Informazioni aggiuntive

Questo tipo di comandi di base non è molto ben documentato, ma cercando un po' in giro qualcosa si trova.

Di solito tutti i libri su unix citano questo comando, ma solo pochi di essi lo trattano con sufficiente dettaglio da dare informazioni utili. La cosa migliore da fare è dare un'occhiata a tutti i libri sui quali si riesce a mettere le mani: non si sa mai dove si possono trovare le informazioni utili.


Sito web mantenuto dal Team degli Editori di LinuxFocus
© Javier Palacios Bermejo
LinuxFocus 1999
Informazioni sulla traduzione:
es -> -- Javier Palacios Bermejo
es -> it Antonio Schifano

1999-10-13, generated by lfparser version 0.7