awk/Einstieg in awk
Ausführen eines awk-Programms
Es gibt mehrere Möglichkeiten, awk über die Befehlszeile aufzurufen:
- Aufruf des Programms ohne Eingabedatei
- Aufruf des Programms mit Eingabedatei
- Aufruf einer Programmdatei mit Eingabedatei
Aufruf des Programms ohne Eingabedatei
awk kann ganz ohne Eingabedatei aufgerufen werden, wobei das Programm dann solange auf die Standardeingabe angewendet wird, bis durch "CTRL+D" das Dateiende angezeigt wird.
awk 'program'
Beispiele
$ awk "BEGIN { print \"Don't panic\" }" Don't panic $ awk '{ print }' Das ist ein Beispiel. Das ist ein Beispiel. CTRL+D
Aufruf des Programms mit Eingabedatei
Kurze Programme können von awk direkt über die Befehlszeile ausgeführt werden, wobei das Programm aus einzelnen Mustern und Aktionen besteht. Um das Programm werden einfache Anführungszeichen gesetzt, damit die Shell keine awk-Zeichen als spezielle Shellzeichen interpretiert. Die einfachen Anführunszeichen bewegen die Shell auch dazu, das ganze Programm als ein einzelnes Argument anzusehen, sodass das Programm länger als eine Zeile sein kann.
awk 'program' inputfile1 inputfile2 ...
Aufruf einer Programmdatei mit Eingabedatei
Längere Programme werden besser in eine Datei geschrieben und in dieser Art von awk über die Befehlszeile ausgeführt.
awk -f programfile inputfile1 inputfile2 ...
Beispiel
$ vi advice.awk BEGIN { print "Don't panic!" } $ awk -f advice.awk Don't panic!
Der awk-Befehl kann auch direkt in eine ausführbare Datei geschrieben werden.
$ vi advice.awk #!/usr/bin/awk -f # Kommentarzeile, die in der Ausgabe nicht angezeigt wird BEGIN { print "Don't panic!" } $ chmod 744 advice.awk $ ./advice.awk Don't panic!
Quoting
Einfache und doppelte Anführungszeichen zu mischen ist schwierig. Es bleibt nichts anderes, als gewisse Tricks anzuwenden. Das folgende Beispiel besteht aus drei verknüpften Zeichenketten: die erste und die dritte arbeiten mit einfachen, die zweite mit doppelten Anführungszeichen.
$ awk 'BEGIN { print "Ein einfaches Anführungszeichen: <'"'"'>" }' Ein einfaches Anführungszeichen: <'>
Diese Schreibweise kann vereinfacht werden zu:
$ awk 'BEGIN { print "Ein einfaches Anführungszeichen: <'\''>" }' Ein einfaches Anführungszeichen: <'>
Eine weitere Möglichkeit ist es, die eingebetteten doppelten Anführungszeichen zu fluchten:
$ awk "BEGIN { print \"Ein einfaches Anführungszeichen: <'>\" }" Ein einfaches Anführungszeichen: <'>
Wenn wirklich sowohl einfache wie doppelte Anführungszeichen verwendet werden müssen, ist es am einfachsten, die Befehle in eine eigene Datei zu schreiben, wo die Shell nicht mitinterpretiert.
Einige Beispiele
Suche in der Datei "bbslist" nach der Zeichenkette "foo". Dabei wird der reguläre Ausdruck "/foo/" verwendet, der das Muster "foo" enthält. Ausgegeben ("print") wird jeweils die aktuelle Zeile ("$0") - da "print" ohne Zusatz immer die aktuelle Zeile ausgibt, könnte hier der Zusatz "$0" auch weggelassen werden.
$ awk '/foo/ { print $0 }' bbslist fooey 555-1234 2400/1200/300 B foot 555-6699 1200/300 B macfoo 555-6480 1200/300 A sabafoo 555-2127 1200/300 C
In einer awk-Regel können entweder das Muster oder die Aktion weggelassen werden, aber nicht beide. Wird das Muster weggelassen, so wird die Aktion für alle Eingabezeilen ausgeführt. Wird die Aktion weggelassen, so werden standardmässig alle Zeilen ausgegeben, auf die das Muster passt.
Ausgabe der Länge der längsten Eingabezeile der Datei "file".
awk '{ if (length($0) > max) max = length($0) } END { print max }' file
Ausgabe jeder Zeile der Datei "file", die länger ist als 80 Zeichen. Als Muster wird hier ein regulärer Ausdruck verwendet; da kein keine Aktion angegeben wurde, wird die Standardaktion angewendet: das Ausgeben der Zeile.
awk 'length($0) > 80' file
Ausgabe der Länge der längsten Zeile der Datei "file". Die Eingabedatei wird vom Programm expand verarbeitet, um Tabulatoren in Leerschläge umzuwandeln.
expand file | awk '{ if (x < length()) x = length() } END { print "Die grösste Zeilenlänge ist " x }'
Ausgabe aller Zeilen der Datei "file", die mindestens ein Feld enthalten. So können beispielsweise Leerzeilen aus einer Datei entfernt werden.
awk 'NF > 0' file
Ausgabe von sieben zufälligen Zahlen zwischen 0 und einschliesslich 100.
awk 'BEGIN { for (i = 1; i <= 7; i++) print int(101 * rand()) }'
Ausgabe der Anzahl Bytes in den Dateien "bbslist" und "inventoryshipped".
ls -l bbslist inventoryshipped | awk '{ x+= $5 } ; END {print "Total bytes: " x }'
Ausgabe der Anzahl Kilobytes in den Dateien "bbslist" und "inventoryshipped".
ls -l bbslist inventoryshipped | awk '{ x+= $5 } END {print "Total K-bytes: " x/1024 }'
Ausgabe einer sortierten Liste mit den Loginnamen aller Benutzer.
awk -F: '{ print $1 }' /etc/passwd | sort
Zählen der Zeilen ind der Datei "file".
awk 'END { print NR }' file
Ausgabe der Zeilen mit gerader Zeilennummer in der Datei "file".
awk 'NR % 2 == 0' file
Ausgabe der Zeilen mit ungerader Zeilennummer in der Datei "file".
awk 'NR % 2 == 1' file
Beispiel mit zwei Regeln
awk liest aus den Eingabedateien jeweils eine Zeile und versucht darauf die Muster jeder Regel anzuwenden. Wenn mehrere Muster passen, so werden mehrere Aktionen gemäss der Reihenfolge wie sie im awk-Programm erscheinen ausgeführt. Passt kein Muster, so werden keine Aktionen ausgeführt.
Nachdem alle Regeln die auf die Zeile passen ausgeführt wurden (also vielleicht auch keine), liest awk die nächste Zeile. Das geschieht solange, bis awk das Dateiende erreicht.
Das folgende Beispiel hat zwei Regeln. Die erste Regel hat die Zeichenkette "12" als Muster und "print $0" als Aktion. Die zweite Regel hat die Zeichenkette "21" als Muster und "print $0" als Aktion. Die Aktion jeder Regel ist in ihre eigenen Klammern eingeschlossen. Das Programm gibt jede Zeile aus, welche die Zeichenkette "12" oder "21" enthält. Falls eine Zeile beide Zeichenketten enthält, wird sie zweimal ausgegeben, je einmal von jeder Regel.
$ awk '/12/ { print $0 } /21/ { print $0 }' bbslist aardvark 555-5553 1200/300 B alpo-net 555-3412 2400/1200/300 A barfly 555-7685 1200/300 A bites 555-1675 2400/1200/300 A core 555-2912 1200/300 C fooey 555-1234 2400/1200/300 B foot 555-6699 1200/300 B macfoo 555-6480 1200/300 A sdace 555-3430 2400/1200/300 A sabafoo 555-2127 1200/300 C sabafoo 555-2127 1200/300 C
Das Programm könnte aus Gründen der Platzersparnis auch wie folgt geschrieben werden:
$ awk '/12/ { print $0 } ; /21/ { print $0 }' bbslist
Ein komplexeres Beispiel
Das folgende Beispiel zeigt, wie awk verwendet werden kann, um die Ausgabe eines anderen Programms zusammenzufassen, auszuwählen und neu zu ordnen.
Das Programm gibt die totale Anzahl Bytes aller Dateien im aktuellen Verzeichnis aus, die zuletzt am 30. Oktober 2007 verändert wurden. Jedes Mal, wenn eine Zeile die Zeichenkette "2007-10-30" als sechstes Feld hat ("$6"), wird die Aktion "sum += $5" ausgeführt, also das fünfte Feld der Ausgabe von "ls -l" zur Variable "sum" hinzugefügt. Nach Verarbeitung der letzten Ausgabezeile von "ls -l" wird die Regel "END" ausgeführt und der Wert der Variable "sum" ausgegeben.
$ ls -l | awk '$6 == "2007-10-30" { sum += $5 } END { print sum }'
awk Anweisungen und Zeilen
Normalerweise ist jede Zeile eines awk-Programms eine eigene Anweisung oder Regel. Allerdings ignoriert gawk Zeilenschaltungen (newlines) nach jedem der folgenden Zeichen und Schlüsselworte:
, { ? : || && do else
Soll eine einzelne Anweisung an einer Stelle fortgesetzt werden, an der eine Zeilenschaltung sie beenden würde, kann sie stattdessen durch Setzen eines umgekehrten Schrägstrichs ("\") fortgesetzt werden. Der umgekehrte Schrägstrich ist an jeder Stelle der Anweisung erlaubt, sogar mitten in einer Zeichenkette oder einem regulären Ausdruck (davon ist allerdings abzuraten). Er muss dafür allerdings zwingend als letztes Zeichen der Zeile stehen.
$ awk '/Dieser reguläre Ausdruck ist zu lang, setze ihn \ darum auf der nächsten Zeile fort/ { print $1 }'
In gawk gibt es keine Begrenzung der Zeilenlänge, sodass dieses Vorgehen niemals zwingend notwendig ist. Aus Lesbarkeitsgründen kann es dennoch z. B. beim Schreiben von Programmdateien verwendet werden.
awk ist eine zeilenorientierte Programmiersprache. Die Aktion jeder Regel muss auf derselben Zeile beginnen wie das zugehörige Muster. Um Muster und Aktion auf zwei verschiendenen Zeilen anzuzeigen muss zwingend der umgekehrte Schrägstrich verwendet werden.