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 pravidloEND
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