BEGIN a END pomocí příkazu awk

Podle manuálu awk se BEGIN a END nepoužívají ke spárování vstupu, ale spíše k zajištění spuštění a čištění -up informace do awk skriptu. Zde je uveden příklad:

ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf 

Nejprve se vytiskne řetězec, který se má odeslat. Pak zkontroluje vstup pro shodu vzoru, kde vstup začíná a nebo x následovaný libovolným znakem jednou nebo mnohokrát následovaným .conf. U všech shod se vytiskne 9. sloupec.

Fakt, který jsme nuceni používat, začíná zde, znamená to, že awk může použít pouze nanejvýš jednu tiskovou funkci, která obsahuje BEGIN nebo END? Pokud ne, tak proč nemůžeme na začátku použít funkci tisku bez klíčového slova BEGIN? Zdá se, že BEGIN je nadbytečný.

Komentáře

  • Pouhé spuštění příkazu bez BEGIN by odpovědělo na vaši otázku a ukázalo, že ' to není nadbytečné a že byste získali jiný výsledek.

Odpověď

BEGIN není nadbytečný. Pokud neurčíte BEGIN, bude print proveden pro každý řádek vstupu.

Citace z manuál :

A BEGIN pravidlo je provedeno pouze jednou, před přečtením prvního vstupního záznamu. Podobně je pravidlo END provedeno pouze jednou, po přečtení všech vstupů.

$ seq 5 | awk "BEGIN{print "Hello"}/4/{print}" # Hello printed once Hello 4 $ seq 5 | awk "{print "Hello"}/4/{print}" # Hello printed for each line of input Hello Hello Hello Hello 4 Hello $ 

odpověď

awk zpracovává každý řádek vstupu pro výrazy uvedené v těle jiné než a END. V případě BEGIN a END bloky, awk zpracuje příkazy pouze jednou, před zahájením zpracování vstupu a po zpracování vstupu resp. efektivně. Bez bloku BEGIN byste nejen nebyli schopni tisknout jednorázové informace, jako jsou záhlaví, ale nebyli byste schopni efektivně inicializovat některé proměnné požadované tělem. FYI, awk program může mít také více BEGIN a END bloků.

Odpověď

awk provede každý blok pouze tehdy, když se vzor před ním shoduje. Prázdný vzor (pouze blok) odpovídá každému řádku. BEGIN a END jsou speciální vzory, které odpovídají začátku a konci souboru (analogicky k významu ^ a $ ve vodorovném směru).

Pokud chcete před čtením souboru něco provést, použijte BEGIN. Například inicializace čítačů nebo tak něco. END by pak mohl shromáždit výsledky.

Odpovědět

V uvedeném příkladu což je podle mého názoru zjednodušeno z důvodu pedagogické jasnosti, máte pravdu, že je to zbytečné. Stejných výsledků byste mohli dosáhnout bez použití BEGIN.

1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 } 

by přineslo stejné výsledky, protože příkaz print je omezeno pouze na první řádek vstupu.

Jak již bylo řečeno, bloky BEGIN a END jsou neuvěřitelně silné nástroje. Jak již bylo zmíněno v jiných řešeních, můžete pomocí bloku BEGIN inicializovat proměnné nebo jiné rutiny, které je třeba provést pouze jednou, ale lze jej také použít ke spuštění příkazů Awk, pokud neexistují žádné soubory ke zpracování. Jednoduchý příklad:

BEGIN { print sqrt(12/4) } 

Můžete vidět vážnější příklad programování v Awk bez zpracování jakéhokoli vstupu zde .

Podobně je blok END mimořádně užitečný pro provádění výpočtů a shrnutí všech vstupů. To „nelze provést (obvykle) bez předchozího načtení všech údajů. Jednoduchý příklad souhrnného vstupu najdete zde

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *