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.
AWK linguaggio di programmazione | |
---|---|
Autore | Alfred Aho, Peter Weinberger, e Brian Kernighan |
Data di origine | 1977 |
Ultima versione | IEEE Std 1003.1-2008 (POSIX) / 1985 |
Utilizzo | può manipolare stringhe, interi e decimali, espressioni regolari |
Paradigmi | scripting, procedurale, data-driven[1] |
Tipizzazione | Debole |
Influenzato da | C, SNOBOL 4, Bourne shell |
Ha influenzato | Tcl, AMPL, Perl, Korn shell (ksh93, dtksh, tksh), Lua |
Implementazione di riferimento | |
Implementazione | awk, GNU Awk, mawk, nawk, MKS AWK, Thompson AWK (compilatore), Awka (compilatore) |
Sistema operativo | Multipiattaforma |
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.
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 ~ /^/)
# ...
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.
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.
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.
# esegue solamente l'istruzione BEGIN ed esce senza leggere alcun input
BEGIN { print "Hello, world!" }
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
Controllo di autorità | LCCN (EN) sh87003812 · GND (DE) 4242961-4 · BNF (FR) cb12302957w (data) · J9U (EN, HE) 987007539008805171 |
---|