Awk

Da tempo immemorabile, Awk ha catturato l'attenzione e l'interesse delle persone in tutto il mondo. Dalla sua origine ad oggi, Awk è stato argomento di discussione, dibattito e riflessione in innumerevoli contesti. Che sia in ambito accademico, scientifico, culturale o sociale, Awk ha lasciato un segno indelebile nella storia dell'umanità. In questo articolo esploreremo le varie sfaccettature, l'impatto e la rilevanza di Awk, nonché la sua influenza su diversi aspetti della vita quotidiana. Attraverso un'analisi approfondita e meticolosa, cercheremo di far luce su questo affascinante argomento e sul suo significato nel mondo moderno.

Disambiguazione – Se stai cercando altri significati, vedi Awk (disambigua).
AWK
linguaggio di programmazione
AutoreAlfred Aho, Peter Weinberger, e Brian Kernighan
Data di origine1977
Ultima versioneIEEE Std 1003.1-2008 (POSIX) / 1985
Utilizzopuò manipolare stringhe, interi e decimali, espressioni regolari
Paradigmiscripting, procedurale, data-driven[1]
TipizzazioneDebole
Influenzato daC, SNOBOL 4, Bourne shell
Ha influenzatoTcl, AMPL, Perl, Korn shell (ksh93, dtksh, tksh), Lua
Implementazione di riferimento
Implementazioneawk, GNU Awk, mawk, nawk, MKS AWK, Thompson AWK (compilatore), Awka (compilatore)
Sistema operativoMultipiattaforma

AWK (dalle iniziali dei cognomi dei suoi autori, Alfred Aho, Peter Weinberger e Brian Kernighan) è un linguaggio di programmazione interpretato orientato alla manipolazione di dati di tipo testuale, sia in forma di file che di flusso di dati provenienti dallo standard input.

Tipi di variabile

AWK è un linguaggio debolmente tipizzato, e qualunque variabile può essere considerata alla stregua di una stringa (può essere concatenata, è possibile contarne il numero di caratteri, eccetera), anche se le variabili numeriche vengono convertite a numeri interi o a virgola mobile quando necessario, ad esempio nelle operazioni aritmetiche. È assente il tipo booleano (ovvero variabili dal valore true o false), ma è possibile usare qualunque variabile come valore booleano: il valore 0, la stringa vuota ("") o una variabile non inizializzata sono considerati false, mentre qualunque altro valore è true.

Oltre alle variabili scalari, AWK supporta anche gli array associativi, cioè array indicizzati tramite stringhe chiave. Poiché in AWK qualunque scalare può essere considerato una stringa, è anche possibile definire array le cui chiavi sono numeri interi sequenziali, ma tipicamente, a differenza di molti altri linguaggi di programmazione, questo non porta alcun vantaggio in termini di prestazioni di accesso, perché AWK non fa distinzione tra array sequenziali e array associativi.

Ad esempio, è possibile definire i due array:

# array "sequenziale"
arr1 = "a"
arr1 = "b"
arr1 = "c"
# array che usa stringhe come chiavi
arr2 = 1
arr2 = 2

L'accesso agli array avviene solitamente tramite la parola chiave in, che cicla sulle chiavi dell'array specificato, con ordine indefinito:

for (i in arr1) {
        print i     # stampa "1", "2", ... in maniera NON sequenziale
}
for (i in arr2) {
        print i     # stampa "foo", "bar" (in maniera sempre non sequenziale)
}

Nel caso di un array sequenziale è possibile usare la sintassi in stile C per ottenere l'accesso sequenziale ai valori:

for (i = 0; i < length(arr1); ++i) {
        print arr1
}

Infine, AWK supporta le espressioni regolari. Un'espressione regolare è definita tra due barre, e viene usato l'operatore tilde per verificare se una variabile soddisfa una data espressione regolare:

# testa se la variabile "foo" inizia con una cifra:
if (foo ~ /^/) 
        # ...

Struttura di un programma

Un programma in AWK è strutturato secondo una sequenza di direttive del tipo:

condizioni { azioni }

Se allo script viene fornito uno o più file, oppure in generale uno stream di dati (ad esempio attraverso lo standard input), questo stream verrà letto riga per riga da AWK; per ogni riga, le istruzioni contenute nello script vengono eseguite sequenzialmente. Per ogni istruzione, se la relativa condizione è verificata per la riga corrente, vengono eseguite le azioni corrispondenti a tale condizione.

Ad esempio, se a un programma AWK siffatto:

# stampa a schermo solamente le righe che consistono solo di lettere minuscole.
/^+$/ {
        print $0
}

viene fornito l'input:

123
pippo
pluto2

verrà eseguita l'azione print $0 (che stampa l'intera riga a schermo) esclusivamente per la seconda riga, mentre le altre due verranno ignorate.

Se viene specificata una condizione senza una relativa azione, l'azione predefinita è proprio "stampa l'intera riga", per cui nell'esempio di sopra il seguente codice sarebbe equivalente:

/^+$/

Se al contrario viene specificata un'azione senza una relativa condizione, quell'azione verrà eseguita per tutte le righe in input.

Condizioni speciali

Esistono due condizioni speciali: BEGIN e END. Un'azione con condizione BEGIN viene eseguita sempre prima che un qualunque input venga processato, mentre una con condizione END viene sempre eseguita dopo che tutto l'input è stato processato.

Utilizzi

AWK può essere usato come filtro, è stato uno dei primi strumenti a fare la sua comparsa dalla versione 7 di Unix ed ottenne la giusta fama di essere un modo per aggiungere capacità computazionali ad una pipeline Unix. L'AWK è ormai presente fra le applicazioni standard di ogni versione recente di sistema operativo Unix disponibile oggi. Implementazioni di AWK esistono comunque per quasi tutti gli altri sistemi operativi.

Solitamente AWK è un linguaggio interpretato, cioè esiste un file eseguibile chiamato awk che legge o da riga di comando o da un file il programma vero e proprio scritto in linguaggio awk e lo applica ad uno o più file di ingresso per produrre un risultato.

Esempi

Esempio d'uso di awk

Hello, world!

# esegue solamente l'istruzione BEGIN ed esce senza leggere alcun input
BEGIN { print "Hello, world!" }

Conteggio delle parole

Conta le parole in input e stampa il numero di righe, parole e caratteri (analogamente al comando wc):

{
    words += NF # NF è il numero di campi (fields) della riga, ovvero il numero di parole
    chars += length + 1 # aggiunge uno alla lunghezza della riga per tenere conto del carattere newline finale
}
END { print NR, words, chars } # NR è il numero di righe dell'input

Note

  1. ^ Michael Stutz, Get started with GAWK: AWK language fundamentals, su developerWorks, IBM, 19 settembre 2006. URL consultato il 23 ottobre 2010 (archiviato dall'url originale il 20 maggio 2011).
    « often called a data-driven language -- the program statements describe the input data to match and process rather than a sequence of program steps»

Altri progetti

Collegamenti esterni

Controllo di autoritàLCCN (ENsh87003812 · GND (DE4242961-4 · BNF (FRcb12302957w (data) · J9U (ENHE987007539008805171