Ricerca nel sito web

Una guida pratica per imparare awk


Ottieni una migliore gestione del comando awk scaricando il nostro eBook gratuito.

Di tutti i comandi Linux disponibili (e ce ne sono molti), i tre più essenziali sembrano essere sed, awk e grep. Forse è il suono arcano dei loro nomi, o l'ampiezza del loro potenziale utilizzo, o semplicemente la loro età, ma quando qualcuno fornisce un esempio di comando "Linux", di solito è uno di questi tre. E mentre sed e grep hanno diversi semplici standard di una riga, il meno prestigioso awk rimane costantemente prominente per essere particolarmente sconcertante.

Probabilmente utilizzerai sed per una rapida sostituzione della stringa o grep per filtrare un modello su base giornaliera. È molto meno probabile che tu componga un comando awk. Spesso mi chiedo il perché di ciò e lo attribuisco ad alcune cose. Prima di tutto, molti di noi usano a malapena sed e grep se non per qualche variazione su questi due comandi:

$ sed -e 's/foo/bar/g' file.txt
$ grep foo file.txt

Quindi, anche se potresti sentirti più a tuo agio con sed e grep, potresti non sfruttare tutto il loro potenziale. Naturalmente non c'è alcun obbligo di saperne di più su sed o grep, ma a volte mi chiedo come "imparo" i comandi. Invece di imparare come funziona un comando, spesso imparo un incantesimo specifico che include un comando. Di conseguenza, spesso sento una falsa familiarità con il comando. Penso di conoscere un comando perché posso nominare tre o quattro opzioni a mente, anche se non so cosa fanno le opzioni e non riesco a mettere il dito sulla sintassi.

E questo è il problema, credo, che molte persone affrontano quando si confrontano con la potenza e la flessibilità di awk.

Imparare awk a usare awk

Le basi di awk sono sorprendentemente semplici. Si nota spesso che awk è un linguaggio di programmazione e, sebbene sia relativamente elementare, è vero. Ciò significa che puoi imparare awk nello stesso modo in cui impari un nuovo linguaggio di programmazione: impara la sua sintassi usando alcuni comandi di base, apprendi il suo vocabolario in modo da poter sviluppare azioni complesse, e poi esercitati, esercitati, esercitati .

Come awk analizza l'input

Awk vede l'input, essenzialmente, come un array. Quando awk esegue la scansione di un file di testo, tratta ogni riga, individualmente e in successione, come un record. Ogni record è suddiviso in campi. Naturalmente, awk deve tenere traccia di queste informazioni e puoi vedere i dati utilizzando NR (numero di record) e NF (numero di campi) variabili integrate. Ad esempio, questo ti dà il conteggio delle righe di un file:

$ awk 'END { print NR;}' example.txt
36

Questo rivela anche qualcosa sulla sintassi di awk. Sia che tu stia scrivendo awk come un one-liner o come uno script autonomo, la struttura di un'istruzione awk è:

pattern or keyword { actions }

In questo esempio, la parola END è una parola chiave speciale e riservata anziché un modello. Una parola chiave simile è BEGIN. Con entrambe queste parole chiave, awk esegue semplicemente l'azione tra parentesi all'inizio o alla fine dell'analisi dei dati.

Puoi usare un modello come filtro o qualificatore in modo che awk esegua una determinata azione solo quando è in grado di abbinare il tuo modello al record corrente. Ad esempio, supponiamo di voler utilizzare awk, proprio come faresti con grep, per trovare la parola Linux in un file di testo:

$ awk '/Linux/ { print $0; }' os.txt
OS: CentOS Linux (10.1.1.8)
OS: CentOS Linux (10.1.1.9)
OS: Red Hat Enterprise Linux (RHEL) (10.1.1.11)
OS: Elementary Linux (10.1.2.4)
OS: Elementary Linux (10.1.2.5)
OS: Elementary Linux (10.1.2.6)

Per awk, ogni riga nel file è un record e ogni parola in un record è un campo. Per impostazione predefinita, i campi sono separati da uno spazio. Puoi cambiarlo con l'opzione --field-separator, che imposta la variabile FS (separatore di campo) su quello che vuoi che sia:

$ awk --field-separator ':' '/Linux/ { print $2; }' os.txt 
 CentOS Linux (10.1.1.8)
 CentOS Linux (10.1.1.9)
 Red Hat Enterprise Linux (RHEL) (10.1.1.11)
 Elementary Linux (10.1.2.4)
 Elementary Linux (10.1.2.5)
 Elementary Linux (10.1.2.6)

In questo esempio è presente uno spazio vuoto prima di ogni elenco perché è presente uno spazio vuoto dopo ogni due punti (:) nel testo di origine. Questo però non è cut, quindi non è necessario che il separatore di campo sia limitato a un carattere:

$ awk --field-separator ': ' '/Linux/ { print $2; }' os.txt 
CentOS Linux (10.1.1.8)
CentOS Linux (10.1.1.9)
Red Hat Enterprise Linux (RHEL) (10.1.1.11)
Elementary Linux (10.1.2.4)
Elementary Linux (10.1.2.5)
Elementary Linux (10.1.2.6)

Funzioni in awk

Puoi creare le tue funzioni in awk usando questa sintassi:

name(parameters) { actions }

Le funzioni sono importanti perché ti consentono di scrivere il codice una volta e riutilizzarlo durante il tuo lavoro. Quando si costruiscono righe di una riga, le funzioni personalizzate sono un po' meno utili di quanto lo siano negli script, ma awk definisce già molte funzioni per te. Funzionano sostanzialmente come qualsiasi altra funzione in qualsiasi altra lingua o foglio di calcolo: impari l'ordine in cui la funzione ha bisogno di informazioni da te e puoi alimentarla con ciò che desideri per ottenere i risultati.

Esistono funzioni per eseguire operazioni matematiche ed elaborazione di stringhe. Quelli matematici sono spesso abbastanza semplici. Fornisci un numero e lo scricchiola:

$ awk 'BEGIN { print sqrt(1764); }'
42

Le funzioni stringa possono essere più complesse ma sono ben documentate nel manuale GNU awk. Ad esempio, la funzione split prende un'entità che awk vede come un singolo campo e la divide in parti diverse. Richiede un campo, una variabile da utilizzare come array contenente ciascuna parte della divisione e il carattere che si desidera utilizzare come delimitatore.

Utilizzando l'output degli esempi precedenti, so che c'è un indirizzo IP alla fine di ogni record. In questo caso, posso inviare solo l'ultimo campo di un record alla funzione split facendo riferimento alla variabile NF perché contiene il numero di campi (e il campo finale deve essere il numero più alto):

$ awk --field-separator ': ' '/Linux/ { split($NF, IP, "."); print "subnet: " IP[3]; }' os.txt
subnet: 1
subnet: 1
subnet: 1
subnet: 2
subnet: 2
subnet: 2

Ci sono molte altre funzioni e non c'è motivo di limitarsi a una per blocco di codice awk. Puoi costruire pipeline complesse con awk nel tuo terminale, oppure puoi scrivere script awk per definire e utilizzare le tue funzioni.

Scarica l'eBook

Imparare awk è principalmente questione di usare awk. Usalo anche se significa duplicare funzionalità che già possiedi con sed o grep o cut o tr o qualsiasi altro comandi perfettamente validi. Una volta che ti senti a tuo agio, puoi scrivere funzioni Bash che invocano i tuoi comandi awk personalizzati per un utilizzo più semplice. E alla fine sarai in grado di scrivere script per analizzare set di dati complessi.

Scarica il nostro eBook per imparare tutto ciò che devi sapere su awk, e inizia a usarlo oggi stesso.

Articoli correlati: