Der Befehl gawk
In diesem Beitrag lernen Sie den Befehl awk bzw. gawk kennen - es handelt sich um die GNU-Implementierung der AWK Programmiersprache. Sie ist konform mit der Definition der Sprache im POSIX 1003.1 Standard und basiert auf der Beschreibung in "The AWK Programming Language" von Aho, Kernighan und Weinberger. gawk bietet die zusätzlichen Funktionen der aktuellen Version von Brian Kernighan's awk sowie verschiedene GNU-spezifische Erweiterungen. Wenn gawk installiert ist, ist awk oft nur ein Symlink zu gawk, sodass mit beiden Befehlen dasselbe Programm aufgerufen wird. Im Folgenden wird immer gawk verwendet. Zudem werden GNU-Erweiterungen entsprechend gekennzeichnet.
Die Grundfunktion von AWK besteht darin, Dateien nach Zeilen oder anderen Texteinheiten zu durchsuchen, die bestimmte Muster aufweisen. Gibt es Übereinstimmungen mit einem Muster, so kann AWK bestimmte Aktionen auf diesen ausführen. AWK führt auf diesem Weg mit der Verarbeitung der Eingabe fort, bis das Ende der Eingabe(-Dateien) erreicht ist. Programme in AWK sind datengesteuert - es werden also die Daten mit denen gearbeitet werden soll sowie die jeweils durchgeführten Aktionen beschrieben. Auf diese Weise unterscheidet sich AWK sich von prozeduralen Sprachen, bei denen das Vorgehen von Programmen in der Regel sehr genau beschrieben wird. AWK-Programme sind entsprechend oft einfacher zu lesen und zu schreiben.
Sie lernen zunächst die allgemeine Syntax des Befehls gawk kennen. Anschließend folgen die wichtigsten Optionen des Befehls sowie einige Grundlagen zur Syntax der AWK Programmiersprache selbst.
Allgemeine Syntax
Die allgemeine Syntax des Befehls gawk lautet:
gawk [Optionen] [Programmtext] [Datei(en)]
Neben optionalen Optionen werden dem Befehl der auszuführende Programmtext sowie darauffolgend eine oder mehrere zu verarbeitende Dateien übergeben. Wenn ein langes Programm ausgeführt werden soll, dann ist es oft sinnvoller, dieses ein eine Datei zu schreiben und diese mithilfe der Option -f an gawk zu übergeben. Der Programmtext wird dann entsprechend nicht mehr im Befehl angegeben:
gawk [Optionen] -f [Programm-Datei] [Datei(en)]
Wichtige Optionen
Im Folgenden werden einige der wichtigsten Optionen des Befehls gawk vorgestellt:
-F - Input-Field-Separator setzen
Mithilfe der Option -F kann der Input-Field-Separator, welcher kontrolliert wie gawk eine Zeile der Eingabe in Felder aufteilt, gesetzt werden. Es kann sich dabei entweder um ein einzelnes Zeichen, oder einen regulären Ausdruck handeln. Eingabezeilen werden dann jeweils nach Zeichenketten durchsucht, die mit dem Input-Field-Separator übereinstimmen, und so aufgeteilt, dass der Text zwischen den Übereinstimmungen jeweils ein Feld bildet.
gawk -F [Input-Field-Separator] [Programmtext] [Datei(en)]
-f - Programmdatei spezifizieren
Bei Verwendung dieser Option wird der AWK-Programmtext nicht dem ersten nicht-Options Argument entnommen, sondern stattdessen aus der angegebenen Datei gelesen. Die Option kann mehrfach verwendet werden - das AWK-Programm besteht dann aus der Konkatenation der Inhalte jeder spezifizierten Datei.
gawk -f [Programm-Datei] [Datei(en)]
Dateien, die mit der Option -f spezifiziert werden, werden so behandelt, wie als hätten sie die folgende Zeile zur Festlegung des Namespace am Anfang stehen:
@namespace "awk"
-v - Variable setzen
Mit der Option -v lässt sich vor dem Beginn der Programmausführung eine Variable mit der Bezeichnung "[Variable]" auf den Wert "[Wert]" setzen. Die Werte der Variablen sind dann innerhalb des BEGIN-Blocks verfügbar. Mit einer Option -v kann jeweils nur eine Variable gesetzt werden, jedoch kann sie mehr als einmal verwendet werden.
gawk -v [Variable]=[Wert] [Programmtext] [Datei(en)]
-c - Kompatibilitäts-Modus
Die Option -c wird verwendet, um den Kompatibilitätsmodus zu aktivieren, in welchem die GNU-Erweiterungen zur AWK-Sprache deaktiviert sind, sodass gawk sich genau wie BWK awk (Version von Brian Kernighan) verhält:
gawk -c [Programmtext] [Datei(en)]
-d - Globale Variablen ausgeben
Mit der Option -d lässt sich eine sortierte Liste aller globalen Variablen, ihrer Typisierungen und Werte in die spezifizierte Datei ausgeben. Wenn keine Datei angegeben wurde, wird die Liste in eine Datei mit der Bezeichnung "awkvars.out" im aktuellen Arbeitsverzeichnis geschrieben. Wird eine Datei angegeben, so sind zwischen der Option -d und der Datei keine Leerzeichen erlaubt:
gawk -d[Datei] [Programmtext] [Datei(en)]
-D - Debugging aktivieren
Das Debugging von AWK-Programmen lässt sich mit der Option -D aktivieren. Der Debugger liest standardmäßig interaktiv, direkt vom Standard-Input stdin, Kommandos ein. Optional kann eine Datei mit einer Liste von Kommandos spezifiziert werden, welche dann nicht-interaktiv von dem Debugger ausgeführt werden. Wenn eine Datei spezifiziert wird, sind zwischen der Option -D und der Datei keine Leerzeichen erlaubt:
gawk -D[Datei] [Programmtext] [Datei(en)]
-e - Programmtext spezifizieren
Die Option -e erlaubt es Ihnen, Programmtext über die Befehlszeile hinzuzufügen. Auf diesem Weg wird es möglich, Quellcode aus Dateien mit Quellcode von der Befehlszeile zu kombinieren. Insbesondere wenn Sie Bibliotheksfunktionen in Ihren Befehlszeilen-Programmen verwenden möchten, ist diese Option hilfreich.
Jede mit einer Option -e angegebene Zeichenkette wird von gawk so behandelt, wie als hätte sie einen Linefeed am Ende stehen - der Aufbau eines vollständigen Programms wird so erleichtert.
gawk -e [Programmtext] [Datei(en)]
-i - Include
Mit der Option -i kann eine AWK-Quellbibliothek aus einer angegebenen Datei gelesen werden. Die Option stellt damit ein vollständiges Äquivalent zur Verwendung von "@include" im Programmtext dar. Die Option ist der Option -f zwar sehr ähnlich, jedoch gibt es zwei wichtige Unterschiede: Zum einen wird eine mit -i angegebene Datei nur geladen, wenn sie nicht zuvor bereits geladen wurde, während die Option -f die angegebene Datei immer lädt. Zum anderen werden mit der Option -i eingelesene Dateien von gawk nicht als Eingabe für das Hauptprogramm (main) erkannt, da die Option für die Verwendung mit Code-Bibliotheken gedacht ist. gawk erwartet entsprechend nach der Verarbeitung einer Option -i weiterhin das Hauptprogramm in einer der Option -f übergebenen Datei oder direkt auf der Befehlszeile.
gawk -i [Programmtext] [Datei(en)]
Dateien, die mit der Option -i spezifiziert werden, werden so behandelt, wie als hätten sie die folgende Zeile zur Festlegung des Namespace am Anfang stehen:
@namespace "awk"
-L - Vor Inkompatibilitäten warnen
Bei Verwendung der Option -L (Lint) warnt gawk vor Konstrukten, die gegenüber anderen awk-Implementierungen bedenklich oder nicht-übertragbar (nicht-portabel) sind. Optional kann eine Zeichenkette "fatal", "invalid" oder "no-ext" übergeben werden, wobei zwischen dieser und der Option selbst keine Leerzeichen erlaubt sind. Die Zeichenkette spezifiziert dabei, welche Warnungen ausgegeben werden:
Zeichenkette | Funktion |
---|---|
fatal | Lint-Warnungen werden zu fatalen Fehlern. |
invalid | Nur Warnungen bezüglich Dingen, die tatsächlich ungültig sind, werden ausgegeben. |
no-ext | Warnungen zu gawk Erweiterungen sind werden deaktiviert. |
Einige Warnungen werden nur ausgegeben, wenn gawk ihr Programm erstmals liest. Andere werden zur Laufzeit ausgegeben.
gawk -L[Zeichenkette] [Programmtext] [Datei(en)]
-P - POSIX-Modus
Wird die Option -P verwendet, so arbeitet gawk in einem strikten POSIX-Modus. Hierdurch werden alle gawk Erweiterungen (wie Option -c), sowie alle solchen Erweiterungen die nicht von POSIX erlaubt werden, deaktiviert.
gawk -P [Programmtext] [Datei(en)]
Werden beide Optionen -P und -c spezifiziert, so erhält -P Vorrang. Zudem wird eine Warnung ausgegeben.
-S - Sandbox-Modus
Die Option -S deaktiviert die Funktion "system()", Eingabeumleitungen mit "getline", Ausgabeumleitungen mit "print" und "printf" sowie dynamische Erweiterungen. Weiterhin wird das Hinzufügen von Dateinamen zu "ARGV", die zum Startzeitpunkt von gawk nicht vorhanden waren, nicht erlaubt. Die Option ist insbesondere dann hilfreich, wenn AWK-Programme aus fraglichen Quellen ausgeführt werden sollen, um sicherzustellen, dass außer den spezifizierten Eingabedateien kein Zugriff durch das Programm auf das System möglich ist.
gawk -S [Programmtext] [Datei(en)]
AWK-Syntax
Ein AWK-Programm besteht immer aus einer Reihe von Regeln, welche jeweils eine Bedingung nach deren Eintreffen gesucht und Anweisungen die bei Eintreffen der Bedingung ausgeführt werden sollen, spezifizieren. Wird keine Bedingung angegeben, so werden die entsprechenden Anweisungen der Regel für jede Eingabezeile ausgeführt. Weiterhin kann auch eine Bedingung ohne Anweisung angegeben werden - in diesem Fall wird über die Standard-Anweisung einfach die Eingabezeile ausgegeben. Optional können in einem AWK-Programm auch eigene Funktionen definiert werden - dazu jedoch später mehr.
Regeln werden normalerweise mithilfe von Zeilenumbrüchen voneinander getrennt - ein typisches AWK-Programm hat damit die folgende Gestalt:
Bedingung { Anweisung }
Bedingung { Anweisung }
...
In den folgenden Abschnitten werden die Konstrukte, die ein AWK-Programm bilden, genauer behandelt.
Bedingungen
Eine der einfachsten möglichen Bedingungen ist der Vergleich der Eingabezeile mit einem regulären Ausdruck. Stimmt die Eingabezeile mit dem regulären Ausdruck überein, so ist die Bedingung wahr und die Anweisungen der Regel werden ausgeführt. Die Bedingung wird dabei wie folgt angegeben, wobei "[regexp]" mit dem entsprechenden regulären Ausdruck zu ersetzen ist:
/[regexp]/
Mit verschiedenen Vergleichsoperatoren lassen sich weitere Bedingungen formulieren. Vergleichsausdrücke, die mit den in der folgenden Tabelle gezeigten Operatoren gebildet werden, haben den Wert 1, wenn sie wahr sind, andernfalls 0. Werden Operanden verschiedener Typisierung verglichen, so werden numerische Operanden in Zeichenketten umgewandelt, wobei der Wert der Variablen "CONVFMT" für die Umwandlung verwendet wird. Der Vergleich von Zeichenketten erfolgt auf Grundlage der lexikographischen Ordnung. Ist eine Zeichenkette ein Präfix einer anderen Zeichenkette, so ist die kürzere Zeichenkette stets kleiner als die längere.
Ausdruck | Funktion |
---|---|
x < y | Wahr, wenn x kleiner als y |
x <= y | Wahr, wenn x kleiner oder gleich y |
x > y | Wahr, wenn x größer als y |
x >= y | Wahr, wenn x größer oder gleich y |
x == y | Wahr, wenn x gleich y |
x != y | Wahr, wenn x ungleich y |
x ~ y | Wahr, wenn x dem regulären Ausdruck y ("/ ... /") entspricht |
x !~ y | Wahr, wenn x dem regulären Ausdruck y ("/ ... /") nicht entspricht |
Schließlich existieren noch die beiden speziellen Bedingungen "BEGIN" und "END", welche Initialisierungs- und Cleanup-Aufgaben in AWK-Programmen ermöglichen. Solche Anweisungen, die sich in einer Regel mit der BEGIN-Bedingung befinden (im Folgenden BEGIN-Block genannt), werden vor dem Einlesen der ersten Eingabezeile ausgeführt. Anweisungen in einer Regel mit END-Bedingung (im Folgenden END-Block genannt) werden dagegen nach dem Einlesen der letzten Eingabezeile ausgeführt. Das Vorhandensein von Anweisungen ist in beiden Fällen Pflicht, da bei ihrer Ausführung keine Eingabezeilen vorhanden sind. Ein AWK-Programm darf mehrere BEGIN- und END-Blöcke beinhalten - sie werden dann in der Reihenfolge ihres Auftretens ausgeführt. In der ursprünglichen Version von AWK aus dem Jahr 1978 durften dagegen nur jeweils ein BEGIN- und ein END-Block pro AWK-Programm vorhanden sein. Weiterhin mussten der BEGIN-Block am Anfang und der END-Block am Ende des Programms positioniert sein - auch diese Einschränkung gilt in aktuellen AWK-Implementierungen nicht mehr.
BEGIN- und END-Block haben somit die folgende Gestalt:
BEGIN { Anweisung }
END { Anweisung }
Felder
Beim Einlesen einer Eingabezeile wird diese automatisch von AWK in eine Reihe von Feldern aufgeteilt. Zur Auftrennung wird der Input-Field-Separator - standardmäßig Whitespace, also eine beliebige Wiederholung von Leerzeichen, Tabs oder Zeilenumbrüchen - verwendet.
Während die gesamte Eingabezeile immer mit "$0" referenziert wird, können mithilfe eines Dollarzeichens "$" und einer direkt darauffolgenden positiven Ganzzahl alle Felder einzeln referenziert werden. In einer Eingabezeile "Ich lerne mit gawk umzugehen." wäre so etwa mit "$1" auf das erste Feld, also die Zeichenkette "Ich" zuzugreifen. Das zweite Feld "lerne" ist mit "$2" erreichbar und so weiter. Eine Angabe "$n" (n ist eine Ganzzahl und n >= 0) im AWK-Programm ist dabei ein gültiger Ausdruck, der den Wert des entsprechenden Feldes repräsentiert.
Variablen
Variablen haben eine Bezeichnung, repräsentieren konkrete Werte (Numerische Werte oder Zeichenketten) und können zur Laufzeit des AWK-Programms genutzt und verändert werden. Die Bezeichnung / der Name einer Variable muss eine Sequenz von Buchstaben (a-z und A-Z), Ziffern (0-9) oder Unterstrichen ("_") sein und darf nicht mit einer Ziffer beginnen. Jede Variable wird standardmäßig mit der leeren Zeichenkette initialisiert, welche nach der Umwandlung in eine Zahl die 0 darstellt.
Ein Variablenname ist ein gültiger Ausdruck, welcher den aktuellen Wert der Variablen repräsentiert. Die Wertzuweisung in einem AWK-Programm erfolgt folgendermaßen:
[Variable]=[Wert]
Es existieren einige eingebaute Variablen mit besonderer Bedeutung. Diese können zwar genauso wie alle anderen Variablen verwendet werden und Werte zugewiesen bekommen, jedoch werden ihre Werte auch automatisch von AWK verwendet und / oder zugewiesen. Die Bezeichnungen der eingebauten Variablen sind alle in Großbuchstaben. Der folgenden Tabelle sind einige der wichtigsten vordefinierten Variablen zu entnehmen:
Variable | Funktion |
---|---|
ARGV | Array der übergebenen Befehlszeilenargumente |
ARGC | Anzahl der übergebenen Befehlszeilenargumente |
ENVIRON | Assoziatives Array der Umgebungsvariablen |
FILENAME | Name der aktuellen Eingabedatei |
NF | Anzahl Felder in der aktuellen Eingabezeile |
NR | Anzahl verarbeiteter Eingabezeilen seit Programmstart. Wird beim Einlesen einer neuen Eingabezeile inkrementiert. |
FNR | Anzahl verarbeiteter Zeilen aus der aktuellen Eingabedatei. Wird beim Einlesen einer neuen Eingabezeile inkrementiert. |
FS | Aktueller Input-Field-Separator |
FIELDWIDTHS | Mit Leerzeichen getrennte Liste von Feldbreiten. Wenn gesetzt werden die Felder nicht mit dem Input-Field-Separator sondern anhand der spezifizierten Feldbreiten aufgeteilt. |
OFS | Aktueller Output-Field-Separator (Ausgabe-Feldtrenner). Wird zwischen Feldern, die mit dem print-Befehl ausgegeben werden, ausgegeben. Standardwert ist " ", also eine Zeichenkette nur mit einem einzelnen Leerzeichen. |
ORS | Aktueller Output-Record-Separator (Ausgabe-Zeilentrenner). Wird am Ende jedes print-Befehls ausgegeben. Standardwert ist "\n" - der Zeilenumbruch. |
Wird ergänzt...
Exit-Status
Wenn das Exit-Statement mit einem einem spezifischen numerischen Wert verwendet wurde, dann beendet gawk und gibt diesen als Exit-Status zurück. Andernfalls wird gawk, wenn während der Ausführung keine Probleme aufgetreten sind, mit dem Wert der C-Konstante "EXIT_SUCCESS" beendet - in der Regel hat sie den Wert 0. Wenn jedoch ein Fehler aufgetreten ist, dann wird gawk mit dem Wert der C-Konstante "EXIT_FAILURE", welche normalerweise den Wert 1 hat, beendet.
Wird gawk aufgrund eines fatalen Fehlers beendet, so ist der Exit-Status 2. Auf nicht POSIX-konformen Systemen könnte dieser Wert jedoch auch auf "EXIT_FAILURE" abgebildet sein.
Abonniere JETZT unseren Newsletter!
Verpasse nie wieder neue Beiträge und exklusive Insider-Only-Inhalte!