Ifølge awk-manualen bruges BEGIN og END ikke til at matche input, men snarere til at give opstart og rengøring -op oplysninger til awk scriptet. Her er eksemplet:
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 udskrives en streng til output. Derefter kontrollerer det input for et mønstermatch, hvor input starter med a eller x efterfulgt af et hvilket som helst tegn en eller flere gange efterfulgt af .conf. For alle matches udskrives den 9. kolonne.
Det faktum, at vi er tvunget til at bruge, begynder her, betyder det, at awk kun højst kan bruge en udskrivningsfunktion, der indeholder BEGIN eller END? Hvis ikke, hvorfor kan vi så ikke bruge udskrivningsfunktionen i starten uden nøgleordet BEGIN? Det ser ud til, at BEGIN er overflødig.
Kommentarer
- At bare køre kommandoen uden BEGIN svarer på dit spørgsmål og viser, at den ' ikke er overflødig, og at du får et andet resultat.
Svar
BEGIN
er ikke overflødig. Hvis du ikke angiver BEGIN
, så udføres print
for hver inputlinje.
Citering fra manual :
A
BEGIN
regel udføres kun én gang, før den første inputpost læses. Ligeledes udføres enEND
-regel kun én gang, når alt input er læst.
$ 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
behandler hver inputlinje for de udtryk, der gives i kroppen, bortset fra BEGIN
og END
blokke. I tilfælde af BEGIN
og END
blokke, awk
behandler kun udsagnene en gang, før behandlingen af input er begyndt og efter behandlingen af input er resp. ektivt. Uden blokken BEGIN
ville du ikke kun være i stand til at udskrive engangsoplysninger såsom overskrifter, du ville ikke være i stand til effektivt at initialisere nogle af de variabler, der kræves af kroppen. Også FYI, et awk
program kan have flere BEGIN
og END
blokke.
Svar
awk
udfører kun hver blok, når mønsteret før det matcher. Tomt mønster (bloker kun) matcher hver linje. BEGIN
og END
er specielle mønstre, der matcher begyndelsen og slutningen af filen (analog med betydningen af ^
og $
i vandret retning).
Hvis du vil have noget at udføre, før du læser filen, skal du bruge BEGIN
. For eksempel initialisering af tællere eller noget. END
kunne derefter samle resultaterne.
Svar
I det givne eksempel, som jeg synes er forenklet for pædagogisk klarhed, har du ret i, at det er overflødigt. Du kunne få de samme resultater uden at bruge BEGIN
.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
ville give de samme resultater, da udskriftserklæringen er begrænset til kun den første linie med input.
Når det er sagt, er BEGIN
og END
-blokkene utroligt kraftige værktøjer. Som andre løsninger har nævnt, kan du bruge BEGIN
-blokken til at initialisere variabler eller andre rutiner, der kun skal udføres en gang, men det kan også bruges til at køre Awk-kommandoer, når der ikke er nogen filer, der skal behandles. Et simpelt eksempel:
BEGIN { print sqrt(12/4) }
Du kan se et mere seriøst eksempel på programmering i Awk uden at behandle noget input her .
Ligeledes er END
-blokken yderst nyttig til udførelse af beregninger og opsummering af alle input. Dette kan “ikke gøres (normalt) uden først at have læst alle dataene. Et simpelt eksempel på opsummering af input kan findes her