I følge awk-manualen brukes BEGIN og END ikke til å matche input, men til å gi oppstart og rengjøring -opp informasjon til awk-skriptet. Her er eksemplet gitt:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Først skrives dette ut en streng som skal sendes ut. Deretter sjekker den inngangen for et mønstermatch, der inngangen starter med a eller x etterfulgt av et hvilket som helst tegn en eller mange ganger etterfulgt av .conf. For alle treff blir den 9. kolonnen skrevet ut.
Det faktum at vi er tvunget til å bruke begynner her, betyr det at awk bare kan bruke maksimalt en utskriftsfunksjon som inneholder en BEGIN eller END? Hvis ikke, hvorfor kan vi da ikke bare bruke utskriftsfunksjonen i begynnelsen uten nøkkelordet BEGYN? Det virker som om BEGIN er overflødig.
Kommentarer
- Bare å kjøre kommandoen uten BEGIN vil svare på spørsmålet ditt og vise at det ' ikke er overflødig, og at du vil få et annet resultat.
Svar
BEGIN
er ikke overflødig. Hvis du ikke spesifiserer BEGIN
, vil print
bli utført for hver linje med inngang.
Sitering fra manual :
A
BEGIN
-regelen utføres bare en gang, før den første inngangsposten leses. På samme måte utføres enEND
-regel bare én gang, etter at all inngangen er lest.
$ 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 $
Svar
awk
prosesser hver inngangslinje for de andre uttrykkene i kroppen enn BEGIN
og END
blokker. I tilfelle BEGIN
og END
blokker, awk
vil behandle utsagnene bare en gang, før behandlingen av input er startet og etter at behandlingen av input er gjort resp. ektivt. Uten BEGIN
-blokken, ville ikke bare du ikke kunne skrive ut engangsinformasjon, for eksempel overskrifter, og du ville ikke kunne initialisere noen av variablene effektivt. Også FYI, et awk
-program, kan ha flere BEGIN
og END
blokker.
Svar
awk
utfører hver blokk bare når mønsteret før det stemmer overens. Tomt mønster (bare blokker) samsvarer med hver linje. BEGIN
og END
er spesielle mønstre som samsvarer med begynnelsen og slutten av filen (analogt med betydningen av ^
og $
i horisontal retning).
Hvis du vil at noe skal utføres før du leser filen, bruker du BEGIN
. For eksempel initialisering av tellere eller noe. END
kunne da samle resultatene.
Svar
I eksemplet gitt, som jeg tror er forenklet for pedagogisk klarhet, har du rett i at det er overflødig. Du kan få de samme resultatene uten å bruke BEGIN
.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
vil gi de samme resultatene siden utskriftsuttalelsen er begrenset til bare den første inngangslinjen.
Når det er sagt, er BEGIN
og END
blokkene utrolig kraftige verktøy. Som andre løsninger har nevnt, kan du bruke BEGIN
-blokken til å initialisere variabler eller andre rutiner som bare trenger å utføres en gang, men den kan også brukes til å kjøre Awk-kommandoer når det ikke er noen filer å behandle. Et enkelt eksempel:
BEGIN { print sqrt(12/4) }
Du kan se et mer seriøst eksempel på programmering i Awk uten å behandle noen inngang her .
På samme måte er END
-blokken ekstremt nyttig for å utføre beregninger og oppsummere alle inngangene. Dette kan ikke gjøres (vanligvis) uten først å ha lest i alle dataene. Et enkelt eksempel på oppsummering av innspill finner du her