co robi getline w awk?

Mam następujący awk skrypt, który przyjmuje następujący plik wejściowy, input.txt i generuje poniższe dane wyjściowe. Czy ktoś może poświęcić trochę czasu na wyjaśnienie, jak działa ten skrypt awk? Spędziłem nad tym trochę czasu i nie ma to większego sensu.


Dane wejściowe:

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

Wyjście:

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

Polecenie uzyskania powyższego wyniku:

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 

Rozumiem, że /FINISHED|INITIATED/ {} oznacza, że polecenia wewnątrz nawiasów klamrowych będą wykonywane tylko w wierszach pasujących do FINISHED lub INITIATED, ale jako o ile mogę stwierdzić z danych wyjściowych, skrypt wydaje się analizować ze wszystkich wierszy. Co się dzieje?

Komentarze

  • Co dokładnie nie ' rozumiesz? Nic? W takim przypadku: czy powinniśmy przeczytać podręcznik awk? W przeciwnym razie: bądź precyzyjny. Dane są wczytywane do zmiennych i wyprowadzane w innej kolejności.
  • Nie ' wiem, co robi funkcja getline w powyższym poleceniu. A także, jeśli podamy wzorzec taki jak ten /FINISHED|INITIATED/, awk wyszukuje odpowiednią linię i wykonuje operację tylko na tej konkretnej linii. Ale operacja została wykonana na wszystkich wierszach. Jak?
  • @HaukeLaging Co Dane są wczytywane do zmiennych i wyprowadzane w innej kolejności oznacza wiersz?

Odpowiedź

Funkcja getline odczytuje następną linię i przenosi do niej skrypt. kolejne getline wywołania przechodzą do następnej linii. Być może łatwiej to zrozumieć na przykładzie:

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

Jak jak widać powyżej, skrypt przetworzy pierwszą linię, ponieważ pasuje ona do foo. Każde wywołanie getline spowoduje odczytanie wiersza następującego po bieżącej, więc kolejne wywołania print powodują wypisanie kolejnych wierszy.

Odpowiedź

Jeśli nie wiesz, co robi funkcja awk, wówczas zwykłą strategią jest aby rzucić okiem na stronę podręcznika:

getline

Ustaw $ 0 z następnego rekordu wejściowego; ustaw NF, NR, FNR, RT

Blok poleceń jest faktycznie wykonywany tylko dwukrotnie. Pozostałe wiersze są obsługiwane przez getline z poziomu blok.

Można to przepisać na:

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

Komentarze

  • Co się stanie, jeśli następny rekord jest pusty?
  • @AvinashRaj Ani Twój kod, ani moja alternatywa nie przeglądają zawartości wierszy (z wyjątkiem /FINISHED|INITIATED/ Linie są po prostu odliczane. Dane muszą być dokładnie ułożone (z pliku awk parsi ng perspektywy) w sposób, który pokazałeś, w przeciwnym razie kod się zepsuje.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *