Mám následující awk skript, který přebírá následující vstupní soubor, input.txt a produkuje výstup níže. Může si prosím někdo udělat čas a rozebrat, jak tento skript awk funguje? Strávil jsem to trochu času a nedává to moc smysl.
Vstup:
$ 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**
Výstup:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
Příkaz k získání výše uvedeného výstupu:
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
Rozumím tomu /FINISHED|INITIATED/ {} znamená, že příkazy uvnitř složených závorek se budou spouštět pouze na řádcích odpovídajících FINISHED nebo INITIATED ale jako pokud vím z výstupu, zdá se, že skript analyzuje všechny řádky. Co se děje?
Komentáře
Odpověď
Funkce getline přečte další řádek a přesune na něj skript. Takže, po sobě jdoucí getline volání se přesunou na další řádek. Tomu se snad snáze porozumí na příkladu:
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
As jak vidíte výše, skript zpracuje první řádek, protože odpovídá foo. Každé volání getline přečte řádek po aktuálním, takže následující print volání tisknou další řádky.
Odpověď
Pokud nevíte, co funkce awk dělá, je obvyklá strategie podívat se na manuálovou stránku:
getline
Nastavit $ 0 z dalšího vstupního záznamu; nastavit NF, NR, FNR, RT
Blok příkazů je skutečně spuštěn pouze dvakrát. Ostatní řádky jsou zpracovány pomocí getline zevnitř blok.
To lze přepsat na:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
Komentáře
- Co se stane, pokud je další záznam prázdný?
- @AvinashRaj Ani váš kód, ani moje alternativa se nedívá na obsah řádků (s výjimkou
/FINISHED|INITIATED/). Řádky se pouze odpočítávají. Data musí být uspořádána přesně (z awk parsi.) ng perspective) způsobem, který jste ukázali, jinak se kód rozbije.
/FINISHED|INITIATED/, awk vyhledá odpovídající řádek a provede operaci pouze na tomto konkrétním řádku. Ale operace byla provedena na všech linkách. Jak?