Jeg har følgende awk
skript som tar følgende inndatafil, input.txt
og produserer utdataene nedenfor. Kan noen ta deg tid til å bryte ned hvordan dette awk
skriptet fungerer? Jeg har brukt litt tid på det, og det gir ikke veldig mye mening.
Inngang:
$ 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**
Utgang:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
Kommando for å få ovennevnte utgang:
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
Min forståelse er at /FINISHED|INITIATED/ {}
betyr at kommandoene inne i krøllete bukseseler bare kjøres på linjer som samsvarer med FINISHED
eller INITIATED
men som så vidt jeg kan se fra utdataene, ser skriptet ut til å analyseres fra alle linjer. Hva skjer?
Kommentarer
Svar
getline
-funksjonen leser neste linje og flytter skriptet til det. Så, påfølgende getline
samtaler flytter til neste linje. Dette er kanskje lettere å forstå med et eksempel:
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
Som du kan se ovenfor, vil skriptet behandle den første linjen fordi den samsvarer med foo
. Hvert anrop til getline
vil lese linjen etter den nåværende, så de påfølgende print
samtalene skriver ut de neste linjene.
Svar
Hvis du ikke vet hva en awk
-funksjon gjør, er den vanlige strategien for å se på mannssiden:
getline
Sett $ 0 fra neste inngangspost; sett NF, NR, FNR, RT
Kommandoblokken utføres faktisk bare to ganger. De andre linjene håndteres via getline
fra blokk.
Dette kan skrives om til:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
Kommentarer
- Hva skjer hvis neste post er tom?
- @AvinashRaj Verken koden din eller alternativet mitt ser på linjens innhold (med unntak av
/FINISHED|INITIATED/
Linjene telles bare ned. Dataene må ordnes nøyaktig (fra en vanskelig parsi ng perspektiv) på den måten du har vist ellers vil koden bryte.
/FINISHED|INITIATED/
, søker awk etter den tilsvarende linjen og utfører bare operasjonen på den aktuelle linjen. Men operasjonen ble utført på alle linjene. Hvordan?