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?