marrakeshh - Fotolia
Linux-Grundlagen: Einführung in die Bearbeitung von Textdateien mit awk
Mit der Skriptsprache awk lassen sich unter Linux Textdateien auswerten und bearbeiten. Diese Einführung vermittelt erste Grundlagen.
Awk ist ein sehr mächtiges Kommandozeilen-Tool für Linux, das allerdings schnell sehr komplex werden kann. In diesem Beitrag geben wir einen Einblick in die Grundlagen.
Awk ist eine Skript- und Programmiersprache, die 1977 von Alfred Aho, Peter Weinberger und Brian Kernighan (die Namensgebung ergibt sich aus den Anfangsbuchstaben der Nachnamen) zur Auswertung strukturierter Textdateien entwickelt wurde. In fast jeder Linux-Distribution gibt es mittlerweile awk-Versionen (beispielsweise nawk und gawk), die sich leicht über die Kommandozeile nutzen lassen. Als Kommandozeilen-Tool kann awk auch über SSH (Secure Shell) genutzt werden.
Mit awk lassen sich Textdateien bearbeiten und auswerten, standardmäßig wird dabei jede Zeile einer Datei als sogenannter Record behandelt. Ein Record wird dann weiter in Sequenzen und Felder aufgeteilt. Awk-Programme sind damit lediglich eine Liste von Aussagen auf Basis bestimmter Muster, die sich auf Records und Felder beziehen. Awk liest sich also von Anfang bis Ende geradlinig durch Dateien und führt entsprechende Handlungen aus, sobald ein bestimmtes Muster erkannt wird.
Der erste awk-Befehl
Als Beispiel nehmen wir einmal an, wir wollen alle Zeilen einer Datei anzeigen, die einen bestimmten Wert enthalten.
Als erstes benötigen wir hierfür natürlich eine Textdatei. Über den ls-Befehl zusammen mit ein paar weiteren Optionen erhalten wir eine Liste der lokalen Festplatte, die wir als Datei nutzen können. Der folgende Befehl nutzt ls zusammen mit –lh und gibt das Ergebnis in der Textdatei rob-list.txt aus.
ls -lh > rob-list.txt
Die daraus resultierende rob-list.txt könnte dann folgendermaßen aussehen:
total 40K
-rw-rw-r-- 1 rob rob 23K Jul 12 15:29 awk-basics.odt
-rw-rw-r-- 1 rob rob 110 Jul 7 12:52 rob2.data
-rw-rw-r-- 1 rob rob 220 Jul 12 16:26 rob3.data
-rwxrwxrwx 1 rob rob 59 Jul 12 16:28 rob.awk
-rw-rw-r-- 1 rob rob 220 Jun 27 10:55 rob.data
-rw-rw-r-- 1 rob rob 0 Jul 12 16:57 rob-list.txt
Um über einen awk-Befehl den Wert „220“ zu finden, müsste folgendes eingegeben werden:
awk '/220/ {print $0}' rob-list.txt
Und hier wäre das Ergebnis:
-rw-rw-r-- 1 rob rob 220 Jul 12 16:26 rob3.data
-rw-rw-r-- 1 rob rob 220 Jun 27 10:55 rob.data
In diesem Fall sucht awk nach dem Text innerhalb der Schrägstriche. Das $0-Feld repräsentiert die gesamte Zeile, es können aber auch nur bestimmte Felder jeder Zeile gewählt werden.
Will man beispielsweise von jeder Zeile lediglich Dateigröße und Dateiname auswählen, dann käme dabei etwas in der Art in Frage: Die Dateigröße wird im Feld 5 angegeben, der Dateiname dagegen im Feld 9. Leerzeichen trennen standardmäßig die Feld-Abfragen. Der daraus resultierende awk-Befehl lautet also:
awk '{print $5 " " $9}' rob-list.txt
Und das Ergebnis wäre:
23K awk-basics.odt
110 rob2.data
220 rob3.data
59 rob.awk
220 rob.data
0 rob-list.txt
Wenn man sich den Text tatsächlich in der Kommandozeile ansieht, dann wird man eine leere Zeile ganz am Anfang bemerken. Das liegt daran, dass awk einfach nur die Felder 5 und 9 anzeigt, auch wenn die Zeile leer ist.
Mögliche Kombinationen des awk-Befehls
Diesen grundlegenden awk-Befehl kann man nun beliebig erweitern. Wenn man beispielsweise nur die Zeilen finden will, die „220“ enthalten, und dabei lediglich Größe und Name der Dateien benötigt, würde dieser Befehl helfen:
awk '/220/ {print $5 " " $9}' rob-list.txt
Das Ergebnis wäre folgendes:
220 rob3.data
220 rob.data
Wenn man dagegen lediglich die Option '/ target string /' ohne weitere Optionen nutzt, dann wird die gesamte Zeile durchsucht. Damit würden auch Zeilen aufgeführt, bei denen der Wert „220“ irgendwo anders auftaucht.
Natürlich handelt es sich bei diesem Beispiel um sehr kleine Textdateien. Awk kann aber auch mit sehr großen Dateien mit hunderten oder tausenden Zeilen Text umgehen. Awk fängt ganz einfach von vorne an, durchsucht Zeile für Zeile den Text und gibt jeden gefundenen Suchtreffer an.
Man kann aber auch noch einen Schritt weiter gehen und zum Beispiel nach bestimmten Mustern in den Feldern selbst suchen. So etwas könnte dann folgendermaßen aussehen:
awk '(index($9, "rob") != 0) && (index($9, "awk") !=0) {print $5" "$9}' rob-list.txt
Das Ergebnis wäre:
59 rob.awk
Hier sucht die index-Funktion in der rob-list.txt nach „rob“ und „awk“. In diesem Fall wurde der &&-Operator genutzt, um die Ergebnisse nach Zeilen zu filtern, die beide Werte enthalten. Soll nach Zeilen gesucht werden, die einen der beiden Werte enthalten, muss der ||-Operator verwendet werden.
Die angezeigten Werte lassen sich auch verändern. Mit einer kleinen Änderung des vorherigen awk-Befehls kann man sich einfach ein „Ich habe es gefunden“ anzeigen lassen, wenn eine Zeile „rob“ und „awk“ zusammen enthält. Der Befehl hierzu sieht so aus:
awk '(index($9, "rob") != 0) && (index($9, "awk") !=0) {print $5" I found it"}' rob-list.txt
Das Ergebnis sieht dann so aus:
59 Ich habe es gefunden
Das ist natürlich nur eine ganz grundlegende Einführung in das Arbeiten mit awk, aber im Internet sind zahlreiche weitere Informationsquellen zu awk vorhanden. Beispielsweise ein gawk User Guide, die awk-Homepage oder ein awk-Tutorial. Es gibt sogar eine awk-Version für Windows. Awk ist keine besonders schwer zu erlernende Skriptsprache und die Vorteile liegen auf der Hand – mit ein bisschen Eingewöhnungszeit sollten Linux-Admins also keine Probleme haben, das Potenzial von awk voll auszuschöpfen.
Folgen Sie SearchDataCenter.de auch auf Twitter, Google+ und Facebook!