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?