Come scrivere uno script awk per creare un semplice conteggio di relazione


Unix è iniziata poco dopo l'alba dell'era dell'informazione. Tra le sue molte storie e fiabe, leggenda di awk proviene direttamente dai famosi Bell Labs ed è chiamato per i suoi inventori, Aho, Kernighan e Weinstein. (Sì, Kernighan. L'uomo !! Dovresti sapere qualcosa sulla storia di C per ottenere il riferimento ...)

Awk è un linguaggio interpretato, con una particolare attenzione per l'analisi del file di testo. Alcuni dei suoi punti di forza importanti includono il supporto per le espressioni regolari e array associativi, simili al suo successore Perl. Se avete la possibilità di saperne di più su Perl e awk vedrà come essi condividono similitudini con il suo predecessore, il linguaggio di programmazione C Personalmente, ho imparato awk un anno o due prima di iniziare Perl, awk perché sembrava essere un po 'più accessibili.




Come parte del progetto GNU, awk è stato riscritto per essere RF e gawk rinominato (GNU awk) per distinguere tra il programma originale. Con poche eccezioni, la maggior parte di sequenza di comandi awk possono essere eseguite da gawk e viceversa. Per questo tutorial, ho intenzione di ignorare la distinzione tra awk e guardarsi intorno e fare semplicemente riferimento come interprete awk. Abbiamo iniziato a scrivere questo script awk.

Guida introduttiva

Se si utilizza Mac OS o Linux, avete tutto il necessario per iniziare: awk viene preinstallato. Se sei in un team, capo di Windows a Sourceforge e afferra UnxUtils download. Una volta abbiamo disfatto e installato, è il momento di aprire il vostro editor di testo preferito e iniziare.

Penso awk come affrontare il file di input con un focus sulle colonne. (Si consiglia di aprire questo riferimento in una fortezza separata a portata di mano, come si legge la finestra tutorial.) L'ingresso file implicitamente aperto in lettura. La struttura di uno script awk è

Risposta pattern {}

dove il modello può essere un'espressione regolare, o una parola chiave, all'inizio o alla fine. Come ogni linea viene letta dal file di input, se il modello corrisponde alla linea, quindi awk valuta risposta. Nella foto sulla copertina di "awk esempio di modello e risposta" dello schermo, per ogni linea di ingresso che contiene la stringa "JDubya" (maiuscole e minuscole), l'intera stringa di input viene stampato sullo standard output .

In riferimento awk, assicuratevi di approfondire l'idea di un separatore di campo (FS) e separatore di record (RS). Queste variabili incluso l'interprete come dividere le linee del file in ingresso (o record) e su come suddividere i record in campi (o colonne).

Built-in variabili Definizione FS separatore di campo RS separatore di record NF numero di campi nel record corrente rapido elenco delle definizioni finora

Dividi in record e campi

Ho detto che awk come avere un focus sulle colonne. Ecco un esempio. Lasciando gli FS e RS al suo default (rispettivamente vuoto e ritorno a capo,), la prossima linea di input viene digitalizzato in dieci aree separate affrontati da $ 1, $ 2, $ 3, ... $ 10.

Ecco dieci parole separate da spazi di nuova linea finito

Come awk analizza questo disco, si ferma alla fine della riga (RS di default). I campi sono le informazioni contenute in un record nel separatore di campo (di default vuoto, come caratteri di spazio o di tabulazione). L'esempio precedente restituisce il campo 1 (o $ 1) come "Qui" $ 2 "è" $ 3 "ten" ... $ 9 "" $ 10 "in carica".

Command Line

Impostazioni, e come richiamare lo script

Per ricordare il tuo primo script awk, il mio primo script.awk, dovete dire all'interprete dove trovare lo script con awk -f, e dove trovare il file di input. Perché è Unix, i tubi di ingresso sono i benvenuti. (Windows può gestire anche tubi, anche se in misura minore). Se non si utilizza il reindirizzamento, è possibile definire in modo esplicito un file di input come parametro alla riga di comando.

awk -F mia-prima-script.awk un file di input

Le variabili built-in FS in RS per cambiare il modo in awk esegue la scansione del file di input. La parola chiave BEGIN dice a awk interpretare la risposta prima di valutare un eventuale controllo. Variabili incorporati possono essere impostati in versi iniziato, ma possono ottenere goffo.

Una scorciatoia utile per impostare le variabili FS della linea di comando è passata -F "FS", dove FS è il separatore di campo desiderata. Uno dei miei preferiti scenari per l'utilizzo di awk è analizzato attraverso file di testo CSV o valori separati da virgola. Diciamo che il mio script si chiama csv.awk, e la mia lama report.csv csv, e supponiamo non ho messo le variabili incorporati csv.awk.

awk -F, -f csv.awk report.csv

Invocando l'opzione della riga di comando -F così ho detto awk interpretare istruzioni csv.awk con una virgola (,) come separatore di campo.

Attrezzatura Punto Verde 313 Blu 436 Rosso 296 i risultati dell'account computer

awk Un po 'più avanzato

Nel 2003 ho inviato una lista di posta elettronica DHCP con un link ad uno script awk per analizzare file di affitto DHCP. (Se si guardano le file, si vedrà il link per www3. Non cercare di fare clic su di esso. Questo server è stato offline per un po '".)

Nel 2005 ha pubblicato uno script di aggiornamento sarà un progetto utile a SUSE Linux DHCP.

Ricordo vagamente la conversazione con il manutentore SUSE del progetto, ma ho dimenticato completamente mailing list DHCP. Quando ho cercato di trovare un link allo script awk nel 2005, Google ha trovato la lista dei messaggi automatici a partire dal 2003. Si tratta di una memoria lunga, Google!

Ho trovato la sceneggiatura e pubblicato in un blocco di codice alla fine di questo articolo. Invia un commento se avete domande su di esso, o se siete interessati a vedere un hub completo dedicato a come funziona.

Genera un semplice conteggio di un file CSV

Si consideri l'esempio della sezione CSV di codice di seguito. Rosso, blu, verde e squadre competono per catturare i punti in quadranti nord, est, sud e ovest. Il CSV riporta il numero di punti per squadra per ogni quadrante, ma chi ha vinto?

Guardare oltre i dati e determinare se le colonne sono normalizzati - cioè per passare da record? No. Sembra che la prima colonna è il nome del computer, la seconda colonna è la sfera, e la terza colonna è il punteggio per i quadranti di squadra.

Le variabili in awk non dichiarate o inizializzate. Basti pensare a un nome e buttarlo via. Quando ho contare il punteggio, davvero non mi interessa ciò che la linea segnata su, perché presumo che tutti i punti sono uguali e richiede solo una somma totale di punti per la squadra. (Vedere la parte superiore dello schermo, con la didascalia: ". La squadra ha")

Si noti il ​​modello che ho usato Condizione: NF == 3 indica il numero di campi per il record, spero, dico awk saltare cattive record formate. Istruzione c [$ 1] + = 3 $ awk lo accumulare il valore corrente colonna 3 in uno slot chiamato dal valore corrente nella colonna 1. Per linea di ingresso 1, che è lo stesso che dire "aggiungere 149 con il valore memorizzato nel valore dell'array Red fessura c ". Poiché c non esiste prima linea 1 ingresso viene inizializzato con un valore di 149 in uno slot chiamato Red. Si scopre che i nostri risultati erano sciatto e hanno dato le voci ricorrenti per ogni squadra. Non ci resta che supporre che la media per tutti di unirsi. Linea 2 file di input è impostato su matrice fessura rossa c 149-183.

Dopo che tutti i file di input vengono elaborati, lo script Stanza da parola chiave END. I x in dell'operatore e crea una variabile x per contenere i valori trovati come iterazione su slot e. Allo stesso modo, la macchina variabile è creata, e come awk passeggiate attraverso le fessure denominati in c, memorizza il nome di ogni slot nella squadra. Per accedere al valore finale di ogni batteria, vedere il nome di slot utilizzando c [PC].

Provare a eseguire lo script all'ingresso del campione, e vedere se si ottiene gli stessi risultati come me. (Vedi la tabella, "I risultati del conto del computer.")

Un ultimo pensiero a lasciare con: non abbiamo ancora discusso gita separatori, ma a quanto pare nulla di simile (SFO), con un valore di default di un vuoto. Non ho incontrato un OFS editing parziale di linea di comando iniziare ad impostare per la camera. Nel comunicato stampa, OFS è inserita tra le variabili che sono separati da virgole (ad esempio squadra premere [squadra] c nell'esempio). Per stampare i risultati come CSV, comma modifica OFS (,) nella stanza preliminari.

Dati di esempio

CSV

Rosso, Nord, 149 Rosso, Nord, 34 Blu, Nord, 154 Verde, Nord, 271 Verde, Nord, 6 Rosso, Est, 38 Blu, Est, 198 Blu, Est, 2 Verde, orientale, 24 Verde, orientale, 9 Rosso, South 1 Rosso, South 1 Blu, Sud, 37 Blu, Sud, 44 Verde, South 1 Rosso, West, 73 Blu, West 1 Verde, West, 2

leases.awk

#!/Usr/bin/awk -f # Autore: Jeff Wilson # Data: 2002 # Licenza: GPL 3.0 ... qualsiasi garanzia, gratis riutilizzato in qualsiasi forma # attesi ingresso: /var/lib/dhcp/db/dhcpd.leases # (Per ottenere i migliori risultati, il processo di pre-locazione # Il file con '-v grep "uid "') # Normalmente invocato, '/var/lib/dhcp/db/dhcpd.leases leases.awk' Formato # output (delimitato da tabulazioni): # Ip, hardware [ip], CompName [ip] Stato [ip], la scadenza del tempo-in-GMT [ip] # Impostare il spaccalegna, RS, i "}" ... Linee di registro Begin {RS = "}"} # Siamo interessati solo i record che sono più alti di molti personaggi- # (5 ​​Perché? Penso che un CRLF può essere di 2 byte ... non è solo LF su BSD?) Lunghezza ($ 0)> 5 {Total ++ # Voglio solo registrare le variabili che cattura, # Quindi ripristinare i valori nulli endtime = "" HWADDR = "" cn = "" st = "" for (i = 1; i 0) hardware [ipaddr] = HWADDR altro hardward [ipaddr] = "NONE" se (lunghezza (CN)> 0) CompName [ipaddr] = cn altro CompName [ipaddr] = "NONE" se (lunghezza (v)> 0) Stato [ipaddr] = st altro Stato [ipaddr] = "NONE" se (lunghezza (ora di fine)> 0) MyTime [ipaddr] = ora di fine altro MyTime [ipaddr] = "NONE" } # Per ogni cattura ipaddr, esposizione ip, hardware e CompName END {for (ip hardware) { se (lunghezza (IP_ONLY)> 0) Stampa ip altro printf ("% s \ t% s \ t% s \ t% s \ t% s \ n" \ ip, hardware [ip], CompName [ip] Stato [ip], mytime [ip]) } }

(0)
(0)

Commenti - 0

Non ci sono commenti

Aggiungi un commento

smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile
Caratteri rimanenti: 3000
captcha