vad gör getline inom awk?

Jag har följande awk skript som tar följande inmatningsfil, input.txt och producerar utdata nedan. Kan någon ta sig tid att bryta ner hur detta awk -skript fungerar? Jag har spenderat lite tid på det och det ger inte mycket mening.


Ingång:

$ 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** 

Utgång:

RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED 

Kommando för att få ovanstående utgång:

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 uppfattning är att /FINISHED|INITIATED/ {} betyder att kommandona inuti de lockiga hakparenteserna endast körs på rader som matchar antingen FINISHED eller INITIATED men som såvitt jag kan se från utdata verkar manuset tolkas från alla rader. Vad händer?

Kommentarer

  • Vad exakt förstår du inte '? Ingenting? I så fall: Ska vi läsa awk-handboken för dig? Annars: Var exakt. Data läses in i variabler och matas ut i annan ordning.
  • Jag don ' t vet vad getline-funktionen i ovanstående kommando gör. Och även om vi ger mönstret så här /FINISHED|INITIATED/ söker awk efter motsvarande rad och gör bara operationen på den aktuella raden. Men operationen utfördes på alla rader. Hur?
  • @HaukeLaging Vilka data läses in i variabler och matas ut i olika ordning rad betyder?

Svar

Funktionen getline läser nästa rad och flyttar skriptet till det. på varandra följande getline samtal flyttas till nästa rad. Detta är kanske lättare att förstå med ett exempel:

$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2 

Som du kan se ovan kommer skriptet att behandla den första raden eftersom den matchar foo. Varje samtal till getline läser raden efter den aktuella, så de efterföljande print samtalen skriver ut nästa rader.

Svar

Om du inte vet vad en awk -funktion gör är den vanliga strategin för att titta på mansidan:

getline

Ställ in $ 0 från nästa ingångspost; ställ in NF, NR, FNR, RT

Kommandoblocket körs verkligen bara två gånger. De andra raderna hanteras via getline inifrån block.

Detta kan skrivas om till:

/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ... 

Kommentarer

  • Vad händer om nästa post är tom?
  • @AvinashRaj Varken din kod eller mitt alternativ tittar på raden (med undantag för /FINISHED|INITIATED/ Raderna räknas bara ner. Uppgifterna måste ordnas exakt (från en awk parsi ng perspektiv) på det sätt du har visat annars kommer koden att brytas.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *