Introduzione
Le utility Linux spesso seguono la filosofia di progettazione di Unix. Si incoraggia l’uso di strumenti piccoli, utilizzare file di testo semplici per l’input e l’output, e operare in modo modulare. Grazie a questa eredità, abbiamo ottime funzionalità di elaborazione del testo con strumenti come sed e awk
.
awk
è sia un linguaggio di programmazione che un elaboratore di testo che puoi utilizzare per manipolare dati di testo in modi molto utili. In questa guida, esplorerai come utilizzare lo strumento da riga di comando awk
e come utilizzarlo per elaborare il testo.
Sintassi di base
Il comando awk
è incluso per impostazione predefinita in tutti i moderni sistemi Linux, quindi non è necessario installarlo per iniziare a usarlo.
awk
è più utile quando si manipolano file di testo formattati in modo prevedibile. Ad esempio, è eccellente nel parsing e nella manipolazione di dati tabulari. Opera su base riga per riga e itera attraverso l’intero file.
Per impostazione predefinita, utilizza gli spazi bianchi (spazi, tabulazioni, ecc.) per separare i campi. Fortunatamente, molti file di configurazione sul tuo sistema Linux utilizzano questo formato.
Il formato di base di un comando awk
è:
Puoi omettere la parte di ricerca o la parte di azione da qualsiasi comando awk
. Per default, l’azione intrapresa se la parte “azione” non è fornita è “stampare”. Questo stampa semplicemente tutte le righe che corrispondono.
Se la parte di ricerca non è fornita, awk
esegue l’azione elencata su ogni riga.
Se entrambe sono fornite, awk
utilizza la parte di ricerca per decidere se la riga corrente riflette il modello, e poi esegue le azioni sulle corrispondenze.
Nella sua forma più semplice, puoi utilizzare awk
come cat
per stampare tutte le righe di un file di testo sullo schermo.
Crea un file favorite_food.txt
che elenca i cibi preferiti di un gruppo di amici:
Ora utilizza il comando awk
per stampare il file sullo schermo:
Vedrai il file stampato sullo schermo:
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
Questo non è molto utile. Proviamo le capacità di filtraggio della ricerca di awk
cercando nel file il testo “sand”:
Outputcarrot sandy
sandwich brian
Come puoi vedere, awk
stampa ora solo le righe che contengono i caratteri “sand”.
Utilizzando le espressioni regolari, puoi mirare a parti specifiche del testo. Per visualizzare solo la riga che inizia con le lettere “sand”, utilizza l’espressione regolare ^sand
:
Questa volta, viene visualizzata solo una riga:
Outputsandwich brian
Allo stesso modo, puoi utilizzare la sezione di azione per specificare quali informazioni vuoi stampare. Ad esempio, per stampare solo la prima colonna, utilizza il seguente comando:
Outputsandwich
Puoi fare riferimento ad ogni colonna (delimitata da spazi) tramite variabili associate al numero della colonna. Ad esempio, la prima colonna è $1
, la seconda è $2
, e puoi fare riferimento all’intera riga con $0
.
Variabili Interne e Formato Espanso
Il comando awk
utilizza alcune variabili interne per assegnare determinate informazioni mentre elabora un file.
Le variabili interne utilizzate da awk
sono:
- FILENAME: Fa riferimento al file di input corrente.
- FNR: Fa riferimento al numero del record corrente relativo al file di input corrente. Ad esempio, se hai due file di input, questo ti direbbe il numero di record di ciascun file invece che in totale.
- FS: Il separatore di campo corrente utilizzato per indicare ogni campo in un record. Per impostazione predefinita, questo è impostato su spazio bianco.
- NF: Il numero di campi nel record corrente.
- NR: Il numero del record corrente.
- OFS: Il separatore di campo per i dati in output. Per impostazione predefinita, questo è impostato su spazio bianco.
- ORS: Il separatore di record per i dati in output. Per impostazione predefinita, questo è un carattere di nuova riga.
- RS: Il separatore di record utilizzato per distinguere i record separati nel file di input. Per default, questo è un carattere di nuova riga.
Puoi cambiare i valori di queste variabili a tuo piacimento per adattarle alle esigenze dei tuoi file. Di solito lo fai durante la fase di inizializzazione del tuo elaborato.
Questo ci porta a un altro concetto importante. La sintassi di awk
è leggermente più complessa rispetto a quanto hai usato finora. Ci sono anche blocchi BEGIN
e END
opzionali che possono contenere comandi da eseguire prima e dopo l’elaborazione del file, rispettivamente.
Questo fa sì che la nostra sintassi espansa assomigli a qualcosa del genere:
I parole chiave BEGIN
e END
sono insiemi specifici di condizioni, proprio come i parametri di ricerca. Si abbinano prima e dopo che il documento sia stato elaborato.
Questo significa che puoi cambiare alcune delle variabili interne nella sezione BEGIN
. Ad esempio, il file /etc/passwd
è delimitato da due punti (:
) invece di spazi bianchi.
Per stampare la prima colonna di questo file, esegui il seguente comando:
Outputroot
daemon
bin
sys
sync
games
man
. . .
Puoi utilizzare i blocchi BEGIN
e END
per stampare informazioni sui campi che stai stampando. Usa il seguente comando per trasformare i dati dal file in una tabella, ben spaziata con tabulazioni utilizzando \t
:
Vedrai questo output:
OutputUser UID GID Home Shell
--------------
root 0 0 /root /bin/bash
daemon 1 1 /usr/sbin /bin/sh
bin 2 2 /bin /bin/sh
sys 3 3 /dev /bin/sh
sync 4 65534 /bin /bin/sync
. . .
---------
File Complete
Come puoi vedere, puoi formattare le cose abbastanza bene sfruttando alcune delle funzionalità di awk
.
Ogni sezione espansa è facoltativa. In realtà, la sezione di azione principale stessa è facoltativa se è definita un’altra sezione. Ad esempio, puoi fare cose del genere:
E vedrai questo output:
OutputWe can use awk like the echo command
Ora vediamo come cercare il testo all’interno dei campi dell’output.
Ricerca dei campi ed espressioni composte
In uno degli esempi precedenti, hai stampato la riga nel file favorite_food.txt
che iniziava con “sand”. Questo è stato facile perché stavi cercando l’inizio dell’intera riga.
Cosa succede se vuoi scoprire se un modello di ricerca corrisponde all’inizio di un campo invece?
Crea una nuova versione del file favorite_food.txt
che aggiunga un numero di elemento di fronte al cibo di ogni persona:
Se vuoi trovare tutti i cibi da questo file che iniziano con “sa”, potresti cominciare provando qualcosa del genere:
Questo mostra tutte le righe che contengono “sa”:
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
In questo caso, stai cercando corrispondenze con qualsiasi istanza di “sa” nella parola. Questo finisce per includere cose come “wasabi” che hanno il modello in mezzo, o “sandy” che non è nella colonna desiderata. In questo caso sei interessato solo alle parole che iniziano con “sa” nella seconda colonna.
Puoi dire ad awk
di corrispondere solo all’inizio della seconda colonna utilizzando questo comando:
Come puoi vedere, questo ci consente di cercare solo all’inizio della seconda colonna per una corrispondenza.
La parte field_num ~
specifica che awk
dovrebbe prestare attenzione solo alla seconda colonna.
Output3 sandwich brian
4 salad ryan
Puoi facilmente cercare anche le cose che non corrispondono includendo il carattere “!” prima del tilde (~). Questo comando restituirà tutte le righe che non hanno un cibo che inizia con “sa”:
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
Se decidi in seguito che sei interessato solo alle righe che non iniziano con “sa” e il numero dell’articolo è inferiore a 5, potresti utilizzare un’espressione composta come questa:
Questo introduce alcuni nuovi concetti. Il primo è la possibilità di aggiungere ulteriori requisiti affinché la riga corrisponda utilizzando l’operatore &&
. Utilizzando questo, puoi combinare un numero arbitrario di condizioni affinché la riga corrisponda. In questo caso, stai utilizzando questo operatore per aggiungere un controllo che il valore della prima colonna sia inferiore a 5.
Vedrai questo output:
Output1 carrot sandy
2 wasabi luke
Puoi utilizzare awk
per elaborare i file, ma puoi anche lavorare con l’output di altri programmi.
Elaborazione dell’Output di Altri Programmi
Puoi utilizzare il comando awk
per analizzare l’output di altri programmi anziché specificare un nome file. Ad esempio, puoi utilizzare awk
per estrarre l’indirizzo IPv4 dal comando ip
.
Il comando ip a
visualizza l’indirizzo IP, l’indirizzo di broadcast e altre informazioni su tutte le interfacce di rete sulla tua macchina. Per visualizzare le informazioni per l’interfaccia chiamata eth0
, usa questo comando:
Vedrai i seguenti risultati:
Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
Puoi utilizzare awk
per individuare la linea inet
e quindi stampare solo l’indirizzo IP:
Il flag -F
dice a awk
di delimitare mediante barre oblique in avanti o spazi utilizzando l’espressione regolare [\/ ]+
. Ciò divide la linea inet 172.17.0.11/16
in campi separati. L’indirizzo IP è nel terzo campo perché gli spazi all’inizio della linea contano anche come un campo, poiché hai delimitato tramite spazi oltre che barre oblique. Nota che awk
ha trattato gli spazi consecutivi come un singolo spazio in questo caso.
L’output mostra l’indirizzo IP:
Output172.17.0.11
Troverai molti casi in cui puoi utilizzare awk
per cercare o analizzare l’output di altri comandi.
Conclusione
Ormai dovresti avere una comprensione di base di come puoi utilizzare il comando awk
per manipolare, formattare e stampare selettivamente file di testo e flussi di testo. Awk è un argomento molto più ampio, tuttavia, ed è effettivamente un intero linguaggio di programmazione completo di assegnazione di variabili, strutture di controllo, funzioni integrate e altro ancora. Puoi usarlo all’interno dei tuoi script per formattare il testo in modo affidabile.
Per saperne di più su awk
, puoi leggere il libro di pubblico dominio gratuito dei suoi creatori che approfondisce molto di più.