Una guida allo scripting awk intermedio

Questo articolo esplora le capacità di awk, che sono più facili da usare ora che sapete come strutturare il vostro comando in uno script eseguibile.

Operatori logici e condizionali

Puoi usare gli operatori logici e (scritto &&) e o (scritto ||) per aggiungere specificità alle tue condizioni.

Per esempio, per selezionare e stampare solo i record con la stringa “viola” nella seconda colonna e un importo inferiore a cinque nella terza colonna:

$2 == "purple" && $3 < 5 {print $1}

Se un record ha “viola” nella colonna due ma un valore maggiore o uguale a 5 nella colonna tre, allora non viene selezionato. Allo stesso modo, se un record corrisponde al requisito della colonna tre ma non ha “viola” nella colonna due, anch’esso non viene selezionato.

Si supponga di voler selezionare ogni record nel vostro file in cui l’importo è maggiore o uguale a otto e stampare un record corrispondente con due asterischi (**). Volete anche contrassegnare ogni record con un valore compreso tra cinque (incluso) e otto con un solo asterisco (*). Ci sono alcuni modi per farlo, e un modo è quello di usare il comando next per istruire awk che dopo aver compiuto un’azione, dovrebbe fermare la scansione e procedere al record successivo.

Ecco un esempio:

NR == 1 {
print $0;
next;
}
$3 >= 8 {
printf "%s\t%s\n", $0, "**";
next;
}
$3 >= 5 {
printf "%s\t%s\n", $0, "*";
next;
}
$3 < 5 {
print $0;
}

Comando BEGIN

Il comando BEGIN permette di stampare e impostare variabili prima che awk inizi la scansione di un file di testo. Per esempio, puoi impostare i separatori dei campi di input e di output all’interno del tuo script awk definendoli in un’istruzione BEGIN. Questo esempio adatta il semplice script dell’articolo precedente per un file con campi delimitati da virgole invece che da spazi bianchi:

Comando END

Il comando END, come BEGIN, ti permette di eseguire azioni in awk dopo che ha completato la sua scansione del file di testo che stai elaborando. Se vuoi stampare i risultati cumulativi di qualche valore in tutti i record, puoi farlo solo dopo che tutti i record sono stati scansionati ed elaborati.

I comandi BEGIN e END vengono eseguiti solo una volta ciascuno. Tutte le regole tra di loro vengono eseguite zero o più volte su ogni record. In altre parole, la maggior parte del vostro script awk è un ciclo che viene eseguito ad ogni nuova linea del file di testo che state elaborando, con l’eccezione delle regole BEGIN e END, che vengono eseguite prima e dopo il ciclo.

Ecco un esempio che non sarebbe possibile senza il comando END. Questo script accetta valori dall’output del comando df Unix e incrementa due variabili personalizzate (used e available) ad ogni nuovo record.

$1 != "tempfs" {
used += $3;
available += $4;
}
END {
printf "%d GiB used\n%d GiB available\n", used/2^20, available/2^20;
}

Salvare lo script come total.awk e provarlo:

df -l | awk -f total.awk

Le variabili used e available agiscono come le variabili in molti altri linguaggi di programmazione. Le si crea arbitrariamente e senza dichiararne il tipo, e vi si aggiungono valori a volontà. Alla fine del ciclo, lo script somma i record nelle rispettive colonne e stampa i totali.

Math

Come probabilmente avrete capito da tutti gli operatori logici e dai calcoli casuali fatti finora, awk fa matematica in modo abbastanza naturale. Questo probabilmente lo rende una calcolatrice molto utile per il vostro terminale. Invece di lottare per ricordare la sintassi piuttosto insolita di bc, potete semplicemente usare awk con la sua speciale funzione BEGIN per evitare il requisito di un argomento per il file:

$ awk 'BEGIN { print 2*21 }'
42
$ awk 'BEGIN {print 8*log(4) }'
11.0904

Indubbiamente, si tratta ancora di un sacco di battitura per semplici (e non così semplici) calcoli, ma non ci vorrebbe molto sforzo per scrivere un frontend, che è un esercizio da esplorare.

Questo articolo è stato adattato da un episodio di Hacker Public Radio, un podcast tecnologico comunitario.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *