Laut awk-Handbuch werden BEGIN und END nicht zum Abgleichen von Eingaben verwendet, sondern zum Starten und Reinigen -up Informationen zum awk-Skript. Hier ist das folgende Beispiel:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Zuerst wird eine Zeichenfolge gedruckt, die ausgegeben werden soll. Anschließend wird die Eingabe auf eine Musterübereinstimmung überprüft, wobei die Eingabe mit einem oder x beginnt, gefolgt von einem oder mehreren Zeichen, gefolgt von der .conf. Für alle Übereinstimmungen wird die 9. Spalte gedruckt.
Die Tatsache, dass wir gezwungen sind, hier zu beginnen, bedeutet, dass awk höchstens eine Druckfunktion verwenden kann, die BEGIN oder END enthält? Wenn nicht, warum können wir dann nicht einfach die Druckfunktion am Anfang ohne das Schlüsselwort BEGIN verwenden? Es scheint, dass BEGIN überflüssig ist.
Kommentare
- Wenn Sie den Befehl einfach ohne BEGIN ausführen, wird Ihre Frage beantwortet und es wird angezeigt, dass ' nicht überflüssig ist und Sie ein anderes Ergebnis erhalten.
Antwort
Die BEGIN
ist nicht überflüssig. Wenn Sie BEGIN
nicht angeben, wird die print
für jede Eingabezeile ausgeführt.
Zitieren von das Handbuch :
A
BEGIN
Regel wird nur einmal ausgeführt, bevor der erste Eingabedatensatz gelesen wird. Ebenso wird eineEND
-Regel nur einmal ausgeführt, nachdem alle Eingaben gelesen wurden.
$ 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 $
Antwort
awk
verarbeitet jede Eingabezeile für die im Body angegebenen Ausdrücke außer BEGIN
und END
Blöcke. Im Fall von BEGIN
und END
Blöcke, awk
verarbeitet die Anweisungen nur einmal, bevor die Verarbeitung der Eingabe begonnen hat und nachdem die Verarbeitung der Eingabe abgeschlossen wurde bzw. effektiv. Ohne den Block BEGIN
könnten Sie nicht nur keine einmaligen Informationen wie z. B. Header drucken, sondern auch einige der vom Body benötigten Variablen nicht effizient initialisieren. Außerdem kann ein awk
-Programm mehrere BEGIN
– und END
-Blöcke haben.
Antwort
awk
führt jeden Block nur aus, wenn das Muster davor übereinstimmt. Das leere Muster (nur Block) entspricht jeder Zeile. BEGIN
und END
sind spezielle Muster, die dem Anfang und Ende der Datei entsprechen (analog zur Bedeutung von ^
und $
in horizontaler Richtung).
Wenn Sie vor dem Lesen der Datei etwas ausführen möchten, verwenden Sie BEGIN
. Zum Beispiel die Initialisierung von Zählern oder so. END
könnte dann die Ergebnisse sammeln.
Antwort
In dem angegebenen Beispiel Was meiner Meinung nach aus pädagogischen Gründen vereinfacht ist, haben Sie Recht, dass es überflüssig ist. Sie könnten dieselben Ergebnisse erzielen, ohne BEGIN
zu verwenden.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
würde dieselben Ergebnisse liefern, da die print-Anweisung lautet beschränkt auf nur die erste Eingabezeile.
Davon abgesehen sind die Blöcke BEGIN
und END
unglaublich leistungsfähig Werkzeuge. Wie bereits erwähnt, können Sie mit dem Block BEGIN
Variablen oder andere Routinen initialisieren, die nur einmal ausgeführt werden müssen. Sie können jedoch auch Awk-Befehle ausführen, wenn keine vorhanden sind zu verarbeitende Dateien. Ein einfaches Beispiel:
BEGIN { print sqrt(12/4) }
Sie sehen ein ernsthafteres Beispiel für die Programmierung in Awk ohne Verarbeitung von Eingaben hier .
Ebenso ist der Block END
äußerst nützlich, um Berechnungen durchzuführen und alle Eingaben zusammenzufassen. Dies kann (normalerweise) nicht ohne vorheriges Lesen aller Daten erfolgen. Ein einfaches Beispiel für die Zusammenfassung von Eingaben finden Sie hier