ce face getline în interiorul awk?

Am următorul script awk care ia următorul fișier de intrare, input.txt și produce rezultatul de mai jos. Poate cineva să-și ia timp să descrie cum funcționează acest script awk? „Am petrecut puțin timp pe el și nu are prea mult sens.


Intrare:

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

Ieșire:

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

Comandă pentru obținerea rezultatului de mai sus:

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 

Înțelegerea mea este că /FINISHED|INITIATED/ {} înseamnă că comenzile din interiorul acoladelor vor fi executate numai pe linii care se potrivesc fie cu FINISHED, fie cu INITIATED din câte îmi dau seama din rezultat, scriptul pare să analizeze din toate liniile. Ce se întâmplă?

Comentarii

  • Ce anume ' nu înțelegi? Nimic? În acest caz: Vă citim manualul awk? În caz contrar: Fiți preciși. Datele sunt citite în variabile și rezultate în ordine diferită.
  • Nu ' Nu știu ce face funcția getline din comanda de mai sus. Și, de asemenea, dacă dăm modelul astfel /FINISHED|INITIATED/, awk caută linia corespunzătoare și efectuați operația numai pe acea linie specială. Dar operațiunea a fost efectuată pe toate liniile. Cum?
  • @HaukeLaging Ce datele sunt citite în variabile și rezultate în ordine diferită înseamnă linia?

Răspuns

Funcția getline citește următoarea linie și mută scriptul către acesta. Deci, apelurile consecutive getline trec la următoarea linie. Acest lucru este probabil mai ușor de înțeles cu un exemplu:

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

puteți vedea mai sus, scriptul va procesa prima linie, deoarece se potrivește cu foo. Fiecare apel către getline va citi linia după cea curentă, astfel încât apelurile print ulterioare imprimă următoarele linii.

Răspuns

Dacă nu știți ce face o funcție awk atunci strategia obișnuită este pentru a arunca o privire asupra paginii man:

getline

Setați 0 $ din următoarea înregistrare de intrare; setați NF, NR, FNR, RT

Blocul de comandă este într-adevăr executat doar de două ori. Celelalte linii sunt tratate prin getline din interiorul bloc.

Acest lucru ar putea fi rescris în:

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

Comentarii

  • Ce se întâmplă dacă următoarea înregistrare este goală?
  • @AvinashRaj Nici codul dvs., nici alternativa mea nu privesc conținutul liniilor (cu excepția /FINISHED|INITIATED/ Liniile sunt doar numărate în jos. Datele trebuie să fie aranjate exact (dintr-un parsi awk ng perspective) în modul în care ați arătat altfel, codul se va sparge.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *