Volgens de awk-handleiding worden BEGIN en END niet gebruikt om invoer te matchen, maar eerder om opstarten en opschonen te bieden -up informatie naar het awk-script. Hier is het gegeven voorbeeld:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Dit drukt eerst een string af om uit te voeren. Vervolgens controleert het de invoer op een patroonovereenkomst, waarbij de invoer begint met een of x gevolgd door een willekeurig teken een of meerdere keren gevolgd door de .conf. Voor alle overeenkomsten wordt de 9e kolom afgedrukt.
Het feit dat we hier moeten beginnen te gebruiken, betekent dat awk maximaal één afdrukfunctie kan gebruiken die wel een BEGIN of END bevat? Zo nee, waarom kunnen we “niet gewoon de printfunctie aan het begin gebruiken zonder het trefwoord BEGIN? Het lijkt erop dat BEGIN overbodig is.
Opmerkingen
- Door simpelweg het commando uit te voeren zonder de BEGIN zou je vraag worden beantwoord, wat aantoont dat het ' niet overbodig is en dat je een ander resultaat zou krijgen.
Antwoord
De BEGIN
is niet overbodig. Als u BEGIN
niet specificeert, dan wordt de print
uitgevoerd voor elke regel invoer.
Citeren uit de handleiding :
A
BEGIN
regel wordt slechts één keer uitgevoerd, voordat het eerste invoerrecord wordt gelezen. Evenzo wordt eenEND
regel slechts één keer uitgevoerd, nadat alle invoer is gelezen.
$ 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 $
Antwoord
awk
verwerkt elke regel met invoer voor de uitdrukkingen die in de hoofdtekst staan, anders dan BEGIN
en END
blokken. In het geval van BEGIN
en END
blokken, awk
zal de instructies slechts één keer verwerken, voordat de verwerking van de invoer is begonnen en nadat de verwerking van de invoer is voltooid, resp ectief. Zonder het BEGIN
-blok zou u niet alleen geen eenmalige informatie, zoals kopteksten, kunnen afdrukken, maar zou u sommige van de variabelen die door de hoofdtekst worden vereist niet efficiënt kunnen initialiseren. Ter informatie: een awk
programma kan meerdere BEGIN
en END
blokken hebben.
Answer
awk
voert elk blok alleen uit als het patroon ervoor overeenkomt. Leeg patroon (alleen blok) komt overeen met elke regel. BEGIN
en END
zijn speciale patronen die overeenkomen met het begin en einde van het bestand (analoog aan de betekenis van ^
en $
in horizontale richting).
Als je iets wilt uitvoeren voordat je het bestand leest, gebruik dan BEGIN
. Bijvoorbeeld initialisatie van tellers of zoiets. END
zou dan de resultaten kunnen verzamelen.
Antwoord
In het gegeven voorbeeld, waarvan ik denk dat het vereenvoudigd is voor pedagogische duidelijkheid, je hebt gelijk dat het overbodig is. U zou dezelfde resultaten kunnen krijgen zonder BEGIN
te gebruiken.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
zou dezelfde resultaten opleveren aangezien de printinstructie is beperkt tot alleen de eerste invoerregel.
Dat gezegd hebbende, de BEGIN
en END
blokken zijn ongelooflijk krachtig gereedschap. Zoals andere oplossingen hebben vermeld, kunt u het BEGIN
-blok gebruiken om variabelen of andere routines te initialiseren die slechts één keer hoeven te worden uitgevoerd, maar het kan ook worden gebruikt om Awk-opdrachten uit te voeren als er geen bestanden om te verwerken. Een eenvoudig voorbeeld:
BEGIN { print sqrt(12/4) }
Je kunt een serieuzer voorbeeld zien van programmeren in Awk zonder enige invoer te verwerken hier .
Evenzo is het END
-blok buitengewoon handig voor het uitvoeren van berekeningen en het samenvatten van alle invoer. Dit kan “(meestal) niet worden gedaan zonder eerst alle gegevens in te lezen. Een eenvoudig voorbeeld van samenvattende invoer is hier te vinden