hva gjør getline i awk?

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

  • Hva forstår du ikke '? Forstår du ingenting? I så fall: Skal vi lese awk-manualen for deg? Ellers: Vær nøyaktig. Data blir lest inn i variabler og utdata i annen rekkefølge.
  • Jeg don ' t vet hva getline-funksjonen i kommandoen ovenfor gjør. Og også hvis vi gir mønsteret som dette /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?
  • @HaukeLaging Hva Data leses inn i variabler og sendes ut i annen rekkefølge linjebetegnelser?

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.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *