Come usare il comando awk su Linux

Un laptop Linux con righe di codice in una finestra terminale.
Fatmawati Achmad Zaenuri / Shutterstock

Su Linux, awk è una dinamo di manipolazione del testo da riga di comando, nonché un potente linguaggio di scripting. Ecco un'introduzione ad alcune delle sue funzioni più interessanti.

Come ha avuto il suo nome

Il awk Il comando fu chiamato usando le iniziali delle tre persone che scrissero la versione originale nel 1977: Alfred Aho, Peter Weinberger e Brian Kernighan. Questi tre uomini provenivano dal leggendario pantheon Unix di AT&T Bell Laboratories. Con il contributo di molti altri da allora, awk ha continuato ad evolversi.

È un linguaggio di scripting completo, nonché un toolkit completo di manipolazione del testo per la riga di comando. Se questo articolo stimola l'appetito, puoi dare un'occhiata a tutti i dettagli awk e la sua funzionalità.

Regole, schemi e azioni

awk lavora su programmi che contengono regole composte da schemi e azioni. L'azione viene eseguita sul testo che corrisponde al modello. I motivi sono racchiusi tra parentesi graffe ({}). Insieme, uno schema e un'azione formano una regola. L'intero awk il programma è racchiuso tra virgolette singole (').

Diamo un'occhiata al tipo più semplice di awk programma. Non ha alcun motivo, quindi corrisponde a ogni riga di testo inserita in esso. Ciò significa che l'azione viene eseguita su ogni riga. Lo useremo sull'output di who comando.

Ecco l'output standard di who:

who

Il comando "chi" in una finestra del terminale.

Forse non abbiamo bisogno di tutte queste informazioni, ma, piuttosto, vogliamo solo vedere i nomi sugli account. Possiamo convogliare l'output da who in awke poi dillo awk per stampare solo il primo campo.

Di default, awk considera un campo come una stringa di caratteri circondata da spazi bianchi, l'inizio di una riga o la fine di una riga. I campi sono identificati da un segno di dollaro ($) e un numero. Così, $1 rappresenta il primo campo, che useremo con il print azione per stampare il primo campo.

Digitiamo quanto segue:

who | awk '{print $1}'

Il

awk stampa il primo campo e scarta il resto della riga.

Siamo in grado di stampare tutti i campi che vogliamo. Se aggiungiamo una virgola come separatore, awk stampa uno spazio tra ciascun campo.

Digitiamo quanto segue per stampare anche l'ora in cui la persona ha effettuato l'accesso (campo quattro):

who | awk '{print $1,$4}'

Il

Esistono un paio di identificatori di campo speciali. Questi rappresentano l'intera riga di testo e l'ultimo campo nella riga di testo:

  • $ 0: Rappresenta l'intera riga di testo.
  • $ 1: Rappresenta il primo campo.
  • $ 2: Rappresenta il secondo campo.
  • $ 7: Rappresenta il settimo campo.
  • $ 45: Rappresenta il 45 ° campo.
  • $ NF: Indica il “numero di campi” e rappresenta l'ultimo campo.

Digiteremo quanto segue per far apparire un piccolo file di testo che contiene una breve citazione attribuita a Dennis Ritchie:

cat dennis_ritchie.txt

Il comando "cat dennis_ritchie.txt" in una finestra del terminale.

Vogliamo awk per stampare il primo, il secondo e l'ultimo campo del preventivo. Nota che sebbene sia racchiuso nella finestra del terminale, è solo una singola riga di testo.

Digitiamo il seguente comando:

awk '{print $1,$2,$NF}' dennis_ritchie.txt

Il

Non conosciamo questa “semplicità”. è il 18 ° campo nella riga di testo e non ci interessa. Quello che sappiamo è che è l'ultimo campo e che possiamo usare $NF per ottenere il suo valore. Il periodo è appena considerato un altro personaggio nel corpo del campo.

Aggiunta di separatori di campi di output

Puoi anche dirlo awk per stampare un carattere particolare tra i campi anziché il carattere spazio predefinito. L'output predefinito da date il comando è leggermente peculiare perché il tempo viene scandito proprio nel mezzo di esso. Tuttavia, possiamo digitare quanto segue e utilizzare awk per estrarre i campi che vogliamo:

date
date | awk '{print $2,$3,$6}'

Il

Useremo il OFS (separatore del campo di output) variabile per inserire un separatore tra mese, giorno e anno. Si noti che di seguito racchiudiamo il comando tra virgolette singole ('), non parentesi graffe ({}):

date | awk 'OFS="https://www.howtogeek.com/" {print$2,$3,$6}'
date | awk 'OFS="-" {print$2,$3,$6}'

Il

Le regole BEGIN ed END

UN BEGIN la regola viene eseguita una volta prima dell'inizio dell'elaborazione del testo. In realtà, è stato eseguito prima awk legge persino qualsiasi testo. Un END la regola viene eseguita al termine di tutta l'elaborazione. Puoi averne più BEGIN e END regole e verranno eseguite in ordine.

Per il nostro esempio di a BEGIN regola, stamperemo l'intero preventivo dal dennis_ritchie.txt file che abbiamo usato in precedenza con un titolo sopra di esso.

Per fare ciò, digitiamo questo comando:

awk 'BEGIN {print "Dennis Ritchie"} {print $0}' dennis_ritchie.txt

Il

Notare la BEGIN la regola ha una propria serie di azioni racchiusa all'interno di una propria serie di parentesi graffe ({}).

Possiamo usare questa stessa tecnica con il comando che abbiamo usato in precedenza per reindirizzare l'output who in awk. Per fare ciò, digitiamo quanto segue:

who | awk 'BEGIN {print "Active Sessions"} {print $1,$4}'

Il

Separatori di campi di input

Se vuoi awk per lavorare con testo che non utilizza spazi bianchi per separare i campi, devi dirgli quale carattere il testo usa come separatore di campi. Ad esempio, il /etc/passwd il file utilizza i due punti (:) per separare i campi.

Useremo quel file e il -F (stringa di separazione) opzione da dire awk usare i due punti (:) come separatore. Digitiamo quanto segue per dirlo awk per stampare il nome dell'account utente e la cartella principale:

awk -F: '{print $1,$6}' /etc/passwd

Il

L'output contiene il nome dell'account utente (o il nome dell'applicazione o del demone) e la cartella home (o il percorso dell'applicazione).

Uscita dal

Aggiunta di motivi

Se tutto ciò a cui siamo interessati sono account utente regolari, possiamo includere un modello con la nostra azione di stampa per filtrare tutte le altre voci. Poiché i numeri ID utente sono uguali o superiori a 1.000, possiamo basare il nostro filtro su tali informazioni.

Digitiamo quanto segue per eseguire la nostra azione di stampa solo quando il terzo campo ($3) contiene un valore di 1.000 o superiore:

awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd

Il = 1000 {comando $ 1, $ 6} '/ etc / passwd “comando in una finestra terminale.” width = “646” height = “147” onload = “pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);” onerror = “this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);”>

Lo schema dovrebbe precedere immediatamente l'azione a cui è associato.

Possiamo usare il BEGIN regola per fornire un titolo per il nostro piccolo rapporto. Digitiamo quanto segue, usando il (n) notazione per inserire un carattere di nuova riga nella stringa del titolo:

awk -F: 'BEGIN {print "User Accountsn-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd

Il = 1000 {comando $ 1, $ 6} '/ etc / passwd “comando in una finestra terminale.” width = “646” height = “212” onload = “pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);” onerror = “this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);”>

I pattern sono espressioni regolari a tutti gli effetti, e sono una delle glorie di awk.

Diciamo che vogliamo vedere gli identificatori universalmente univoci (UUID) dei file system montati. Se cerchiamo nel /etc/fstab file per occorrenze della stringa “UUID”, dovrebbe restituirci tali informazioni.

Usiamo il modello di ricerca “/ UUID /” nel nostro comando:

awk '/UUID/ {print $0}' /etc/fstab

Il

Trova tutte le occorrenze di “UUID” e stampa quelle righe. In realtà avremmo ottenuto lo stesso risultato senza il print azione perché l'azione predefinita stampa l'intera riga di testo. Per chiarezza, tuttavia, è spesso utile essere espliciti. Quando guardi attraverso uno script o il tuo file di cronologia, sarai felice di aver lasciato indizi per te stesso.

La prima riga trovata era una riga di commento e sebbene la stringa “UUID” sia al centro di essa, awk l'ho ancora trovato. Possiamo modificare l'espressione regolare e dirlo awk per elaborare solo le righe che iniziano con “UUID”. Per fare ciò, digitiamo quanto segue che include l'inizio del token di linea (^):

awk '/^UUID/ {print $0}' /etc/fstab

Il

Così va meglio! Ora vediamo solo le istruzioni di montaggio originali. Per perfezionare ulteriormente l'output, digitiamo quanto segue e limitiamo la visualizzazione al primo campo:

awk '/^UUID/ {print $1}' /etc/fstab

Il

Se avessimo più file system montati su questa macchina, avremmo una tabella ordinata dei loro UUID.

Funzioni integrate

awk ha molte funzioni che puoi chiamare e usare nei tuoi programmi, sia dalla riga di comando che negli script. Se fai qualche scavo, lo troverai molto fruttuoso.

Per dimostrare la tecnica generale per chiamare una funzione, ne esamineremo alcune numeriche. Ad esempio, quanto segue stampa la radice quadrata di 625:

awk 'BEGIN { print sqrt(625)}'

Questo comando stampa l'arctangente di 0 (zero) e -1 (che risulta essere la costante matematica, pi):

awk 'BEGIN {print atan2(0, -1)}'

Nel seguente comando, modifichiamo il risultato di atan2() funzione prima di stamparlo:

awk 'BEGIN {print atan2(0, -1)*100}'

Le funzioni possono accettare espressioni come parametri. Ad esempio, ecco un modo contorto per chiedere la radice quadrata di 25:

awk 'BEGIN { print sqrt((2+3)*5)}'

Il

script awk

Se la tua riga di comando diventa complicata o sviluppi una routine che sai di voler utilizzare di nuovo, puoi trasferire la tua awk comando in uno script.

Nel nostro script di esempio, eseguiremo tutte le seguenti operazioni:

  • Indica alla shell quale eseguibile utilizzare per eseguire lo script.
  • Preparare awk per usare il FS variabile separatore di campo per leggere il testo di input con campi separati da due punti (:).
  • Usa il OFS separatore del campo di uscita da dire awk usare due punti (:) per separare i campi nell'output.
  • Impostare un contatore su 0 (zero).
  • Imposta il secondo campo di ogni riga di testo su un valore vuoto (è sempre una “x”, quindi non è necessario vederlo).
  • Stampa la riga con il secondo campo modificato.
  • Incrementa il contatore.
  • Stampa il valore del contatore.

Il nostro script è mostrato di seguito.

Esempio di uno script awk in un editor.

Il BEGIN la regola esegue le fasi preparatorie, mentre la END la regola visualizza il valore del contatore. La regola di mezzo (che non ha né nome né motivo in modo che corrisponda a ogni riga) modifica il secondo campo, stampa la linea e incrementa il contatore.

La prima riga dello script indica alla shell quale eseguibile utilizzare (awk, nel nostro esempio) per eseguire lo script. Passa anche il -f (nome file) opzione a awk, che lo informa che il testo che elaborerà verrà da un file. Passeremo il nome file allo script quando lo eseguiamo.

Abbiamo incluso lo script di seguito come testo per consentirti di tagliare e incollare:

#!/usr/bin/awk -f

BEGIN {
  # set the input and output field separators
  FS=":"
  OFS=":"
  # zero the accounts counter
  accounts=0
}
{
  # set field 2 to nothing
  $2=""
  # print the entire line
  print $0
  # count another account
  accounts++
}
END {
  # print the results
  print accounts " accounts.n"
}

Salvalo in un file chiamato omit.awk. Per rendere eseguibile lo script, digitiamo quanto segue usando chmod:

chmod +x omit.awk

Il comando "chmod + x omit.awk" in una finestra del terminale.

Ora, lo eseguiremo e passeremo il /etc/passwd file nello script. Questo è il file awk elaborerà per noi, utilizzando le regole all'interno dello script:

./omit.awk /etc/passwd

Il comando "./omit.awk / etc / passwd" in una finestra del terminale.

Il file viene elaborato e viene visualizzata ogni riga, come mostrato di seguito.

Uscita da "./omit.awk / etc / passwd" in una finestra del terminale.

Le voci “x” nel secondo campo sono state rimosse, ma si noti che i separatori di campo sono ancora presenti. Le righe vengono contate e il totale viene indicato nella parte inferiore dell'output.

awk non significa imbarazzante

awk non significa imbarazzante; è sinonimo di eleganza. È stato descritto come filtro di elaborazione e autore di report. Più precisamente, sono entrambi o, piuttosto, uno strumento che puoi utilizzare per entrambe queste attività. In poche righe, awk raggiunge ciò che richiede una codifica estesa in una lingua tradizionale.

Tale potere è sfruttato dal semplice concetto di regole che contengono schemi, che selezionano il testo da elaborare e azioni che definiscono l'elaborazione.

Articoli correlati

Ultimi articoli