Ho questo awk
script che accetta il seguente file di input, input.txt
e produce loutput di seguito. Qualcuno può prendersi del tempo per analizzare come funziona questo script awk
? Ci ho passato un po di tempo e non ha molto senso.
Input:
$ cat input.txt
FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque**
Output:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
Comando per ottenere luscita precedente:
awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt
La mia comprensione è che /FINISHED|INITIATED/ {}
significa che i comandi allinterno delle parentesi graffe verranno eseguiti solo sulle righe che corrispondono a FINISHED
o INITIATED
ma come per quanto ne so dalloutput, lo script sembra analizzare da tutte le righe. Cosa “sta succedendo?
Commenti
- Che cosa ' non capisci esattamente? Niente? In tal caso: possiamo leggere il manuale di awk per voi? Altrimenti: essere precisi. I dati vengono letti in variabili e restituiti in un ordine diverso.
- I don ' Non so cosa fa la funzione getline nel comando precedente. Inoltre, se diamo il modello in questo modo
/FINISHED|INITIATED/
, awk cerca la riga corrispondente ed esegue loperazione solo su quella particolare riga. Ma loperazione è stata eseguita su tutte le righe. Come? - @HaukeLaging Cosa significa I dati vengono letti nelle variabili e vengono emessi in un ordine diverso riga?
Risposta
La funzione getline
legge la riga successiva e vi sposta lo script. Quindi, chiamate getline
consecutive passano alla riga successiva. Questo è forse più facile da capire con un esempio:
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
As come puoi vedere sopra, lo script elaborerà la prima riga perché corrisponde a foo
. Ogni chiamata a getline
leggerà la riga dopo quella corrente, quindi le successive chiamate print
stampano le righe successive.
Risposta
Se non sai cosa fa una funzione awk
, la strategia usuale è per dare unocchiata alla pagina man:
getline
Imposta $ 0 dal record di input successivo; imposta NF, NR, FNR, RT
Il blocco di comando viene effettivamente eseguito solo due volte. Le altre righe vengono gestite tramite getline
dallinterno del blocco.
Questo potrebbe essere riscritto in:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
/FINISHED|INITIATED/
Le righe vengono semplicemente contate alla rovescia I dati devono essere disposti esattamente (da un awk parsi ng prospettiva) nel modo in cui hai mostrato altrimenti il codice si romperà.