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: |
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.
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:
|
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.
ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
ls -p | grep /$ | wk '{print "rm -r "$1}'
)
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 [email protected], with a Cc: to [email protected]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=
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).
awk
), questo non è troppo difficile:
BEGIN { printf "LaTeX preamble" printf "\\begin{tabular}{|c|c|...|c|}" } |
{ printf $1" & " printf $2" & " . . . printf $n" \\\\ " printf "\\hline" } |
END { print "\\end{document}" } |
|
( $1 == "====>" ) { NomObj = $2 TotObj = $4 if ( TotObj > 0 ) { FS = "|" for ( cont=0 ; cont<TotObj ; cont++ ) { getline print $2 $4 $5 $3 >> NomObj } FS = " " } } |
NOTA: In effetti, il nome dell'oggetto non era specificato, e l'operazione è stata leggermente più complessa, ma questo vuole essere solo un esempio illustrativo. |
BEGIN { BEGIN_MSG = "From" BEGIN_BDY = "Precedence:" MAIN_KEY = "Subject:" VALIDATION = "[MONTH REPORT]" HEAD = "NO"; BODY = "NO"; PRINT="NO" OUT_FILE = "Month_Reports" } { if ( $1 == BEGIN_MSG ) { HEAD = "YES"; BODY = "NO"; PRINT="NO" } if ( $1 == MAIN_KEY ) { if ( $2 == VALIDATION ) { PRINT = "YES" $1 = ""; $2 = "" print "\n\n"$0"\n" > OUT_FILE } } if ( $1 == BEGIN_BDY ) { getline if ( $0 == "" ) { HEAD = "NO"; BODY = "YES" } else { HEAD = "NO"; BODY = "NO"; PRINT="NO" } } if ( BODY == "YES" && PRINT == "YES" ) { print $0 >> OUT_FILE } } |
Supponiamo di amministrare una mailing list e che, di tanto in tanto,
vengano inviati messaggi speciali (per esempio, rapporti mensili)
in qualche formato specifico (ad esempio aventi subject '[MONTH REPORT] mese , dipartimento').
D'un tratto decidiamo che alla fine dell'anno vogliamo mettere insieme tutti
questi messaggi, salvando gli altri da un'altra parte.
Questo può essere fatto trattando lo spool della posta con il programma awk a sinistra. Per ottenere la scrittura di ogni rapporto su un file diverso sono sufficienti tre linee in più di codice. |
NOTA: Questo esempio assume che lo spool della posta sia struttrato nel modo in cui io penso che sia. Effettivamente non ne conosco il formato reale, ma questo programma funziona nella mia installazione (e ancora, in qualche caso strano potrebbe non funzionare). |
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.
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.
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.
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.
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.
Questo tipo di comandi di base non è molto ben documentato, ma cercando un po' in giro qualcosa si trova.
man awk
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:
|
1999-10-13, generated by lfparser version 0.7