BEGIN og END med kommandoen awk

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 en END -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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *