original in es Javier Palacios Bermejo
es to en Javier Palacios Bermejo,Ruben Sotillo, Manuel Rodriguez
en to de Katja Socher
Javier schreibt an seiner Doktorarbeit in Astronomie an einer spanischen Universität, wo er ein Workstation Cluster administriert. Die tägliche Arbeit in seinem Fachbereich wird auf Unixmaschinen erledigt. Nach einigen anfänglichen Problemen und Versuchen wurde die Slackware Linux Distribution gewählt. Linux stellte sich als sehr viel besser als andere proprietäre Unixsysteme heraus.
Dieser Artikel vermittelt einige Einblicke in die Tricks, die man mit AWK machen kann. Es ist kein Tutorial, enthält aber viele nützliche Beispiele.
Ursprünglich kam mir die Idee diesen Text zu schreiben, nachdem ich zwei in LinuxFocus veröffentlichte Artikel von Guido Socher gelesen hatte. Einer davon, über find und ähnliche Befehle, zeigte mir, daß ich nicht der einzige war, der die Kommandozeile benutzte. Oft ist es so, daß schöne GUIs einem nicht verraten, wie die Dinge wirklich ablaufen (das ist der Weg, den Windows vor Jahren beschritten hat). Der andere Artikel war über reguläre Ausdrücke. Obwohl reguläre Ausdrücke in diesem Artikel nur oberflächlich erwähnt werden, muß man sie kennen, um das Maximum aus awk und anderen Befehlen wie sed und grep herausholen zu können.
Die Schlüsselfrage ist, ob der awk Befehl wirklich nützlich ist. Die Antwort
lautet definitiv ja! Er könnte für einen normalen Benutzer nützlich sein, um
Textdateien zu bearbeiten, sie zu reformatieren etc...
Für einen Systemadministrator ist AWK ein wirklich sehr wichtiges Hilfsmittel.
Z.b /var/yp/Makefile
oder schau dir die
Initialisierungsscripte an. AWK findet sich überall.
Das erste Mal, daß ich von AWK hörte, ist nichtig genug und lange genug her, um
in Vergessenheit geraten zu sein. Ich hatte einen Kollegen, der mit ein paar
wirklich großen Dateien auf einem kleinen Cray-Rechner arbeiten mußte. Die
Handbuchseite für awk
in dem Cray war klein, aber er sagte, daß AWK
sehr stark danach aussähe, wie das, was er bräuchte, obwohl er noch nicht
verstanden hatte, wie es zu benutzen sei.
Eine lange Zeit später, wieder in meinem Leben. Ein Kollege von mir benutzte
AWK, um die erste Spalte aus einer Tabelle einer Datei mit dem folgenden Befehl
herauszuziehen:
|
Wenn wir einmal die Lektion gelernt haben, wie man eine Spalte herauszieht, dann
können wir Dinge tun, wie das Umbenennen von Dateien (append .new to "files_list"):
ls files_list | awk '{print "mv "$1" "$1".new"}' | sh |
... und mehr:
ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
ls -l|awk '$1!~/^drwx/{print $9}'|xargs rm
ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
ls -p | grep /$ | wk '{print "rm -r "$1}'
ls -l|awk '$1~/^d.*x/{print $9}'|xargs rm -r
kill `ps auxww | grep netscape | egrep -v grep | awk '{print $2}'`
Wie du siehst, ist AWK wirklich sehr hilfreich, wenn dieselben Berechnungen sich immer wieder wiederholen ... und außerdem macht es auch viel mehr Spaß, ein AWK Programm zu schreiben, statt zwanzigmal mit Hand dasselbe zu machen.
awk
ist eine kleine Programmiersprache, mit einer Syntax, die C in
vielen Aspekten
sehr ähnlich ist. Es ist eine Interpretersprache und der awk
Interpreter
bearbeitet die Anweisungen.
Über die Syntax des awk Befehlsinterpreters:
# gawk --help Usage: gawk [POSIX or GNU style options] -f progfile [--] file ... gawk [POSIX or GNU style options] [--] 'program' file ... POSIX options: GNU long options: -f progfile --file=progfile -F fs --field-separator=fs -v var=val --assign=var=val -m[fr] val -W compat --compat -W copyleft --copyleft -W copyright --copyright -W help --help -W lint --lint -W lint-old --lint-old -W posix --posix -W re-interval --re-interval -W source=program-text --source=program-text -W traditional --traditional -W usage --usage -W version --versionAnstatt einfach die Programme in der Kommandozeile in Anführungszeichen (') zu setzen, können wir, wie du oben sehen kannst, die Anweisungen in eine Datei schreiben und sie mit der Option
-f
aufrufen.
Mit auf der Kommandozeile definierten Variablen ( durch -v
var=
Awk ist, grob gesprochen, dafür gemacht worden, Tabellen zu verwalten. Dies sind einige Informationen, die innerhalb von Feldern und records gruppiert werden können. Der Vorteil dabei ist, daß die record Definition (und die Felddefinition) flexibel ist.
Awk ist mächtig. Es wurde entworfen, um mit einzeiligen Records zu arbeiten, aber dieser Punkt konnte erweitert werden. Damit du einige dieser Aspekte siehst, schauen wir uns einige illustrative (und wirkliche) Beispiele an.
BEGIN { printf "LaTeX preample" printf "\\begin{tabular}{|c|c|...|c|}" } |
{ printf $1" & " printf $2" & " . . . printf $n" \\\\ " printf "\\hline" } |
END { print "\\end{document}" } |
|
( $1 == "====>" ) { NomObj = $2 TotObj = $4 if ( TotObj > 0 ) { FS = "|" for ( cont=0 ; cont<TotObj ; cont++ ) { getline print $2 $4 $5 $3 >> NomObj } FS = " " } } |
Tatsächlich wurde der Objektname nicht zurückgegeben und alles war ein bißchen komplizierter, aber dies soll nur ein illustratives Beispiel sein. |
BEGIN { BEGIN_MSG = "From" BEGIN_BDY = "Precedence:" MAIN_KEY = "Subject:" VALIDATION = "[MONTH REPORT]" HEAD = "NO"; BODY = "NO"; PRINT="NO" OUT_FILE = "Month_Reports" } { if ( $1 == BEGIN_MSG ) { HEAD = "YES"; BODY = "NO"; PRINT="NO" } if ( $1 == MAIN_KEY ) { if ( $2 == VALIDATION ) { PRINT = "YES" $1 = ""; $2 = "" print "\n\n"$0"\n" > OUT_FILE } } if ( $1 == BEGIN_BDY ) { getline if ( $0 == "" ) { HEAD = "NO"; BODY = "YES" } else { HEAD = "NO"; BODY = "NO"; PRINT="NO" } } if ( BODY == "YES" && PRINT == "YES" ) { print $0 >> OUT_FILE } } |
Vielleicht verwalten wir eine Mailingliste und von Zeit zu Zeit werden einige
spezielle Nachrichten (z.B. monatliche Berichte)
in einem speziellen Format (subject als '[Monatsbericht] Monat , Abteilung')
an die Liste geschickt.
Plötzlich, am Ende des Jahres entscheiden wir uns all diese Nachrichten
zusammen, getrennt von den anderen, zu speichern.
Dies kann durch Bearbeitung der mail spool mit dem awk Programm links erreicht werden. Um jeden Bericht, der in eine individuelle Datei geschrieben wurde, zu bekommen, müssen wir drei Zeilen Extra-Code schreiben. |
Bemerkung: Bei diesem Beispiel wird angenommen, daß die mail spool strukturiert ist, wie ich denke, daß sie es ist. Dieses Programm arbeitet für meine Post. |
Ich habe awk für viele andere Aufgaben benutzt (automatisches Generieren von
Webseiten mit Informationen von einfachen Datenbanken) und ich weiß genug über
awk Programmierung, um sicher zu sein, daß man damit eine Menge tun kann.
Laß
deinem Vorstellungsvermögen freien Lauf.
Ein ProblemEin Problem ist, daß awk perfekte Tabelleninformationen benötigt und keine Löcher (Leerzeichen) duldet, awk arbeitet z.B. nicht mit festen Weiten von Spalten. Dies ist nicht problematisch, wenn wir selbst den awk Input erzeugen: Wähle etwas Ungewöhnliches, um die Felder zu trennen, später reparieren wir das mitFS und wir sind fertig!!! Wenn wir den Input schon haben, kann es
dagegen
ein bißchen problematischer sein.
Z.B. könnte eine Tabelle so aussehen:
1234 HD 13324 22:40:54 .... 1235 HD122235 22:43:12 ....Dies ist schwierig mit awk zu handhaben. Leider kommt es recht oft vor. Wenn wir nur eine Spalte mit diesen Charakteristiken haben, können wir das Problem lösen (wenn jemand weiß, wie man es mit mehr als einer Splate in einem allgemeinen Fall macht, laß es mich bitte wissen!). Ich mußte mich mit einer solchen Tabelle, ähnlich zu der oben beschriebenen, herumschlagen. Die zweite Spalte war ein Name und es schloß eine variable Anzahl von Leerzeichen ein. Wie es oft vorkommt, mußte ich sie nach der letzten Spalte sortieren. |
... und eine LösungIch erkannte, daß die Spalte, die ich ordnen wollte die letzte war und awk weiß, wieviele Felder es im laufenden Register gibt. Deshalb war es ausreichend, auf die letzte Spalte zuzugreifen (manchmal$4 , und
manchmal $5 , aber immer NF ).
Am Ende des Tages hatte ich das gewünschte Ergebnis:
awk '{ printf $NF;$NF = "" ;printf " "$0"\n" }' | sort Dies verschiebt einfach die letzte Spalte zur ersten Position und man kann es sortieren. Offensichtlich kann diese Methode leicht auf ein Feld, das das dritte vom Ende ist oder ein Feld, das nach einem Steuerungsfeld kommt, das immer den gleichen Wert hat, angewendet werden. Benutze einfach deine Ideen und dein Vorstellungsvermögen. |
Bis jetzt haben fast alle Beispiele alle Inputdateizeilen bearbeiten. Aber, wie auch die Handbuchseite bemerkt, ist es möglich, nur einige Inputzeilen zu bearbeiten. Man muß nur die Gruppe von Befehlen mit der Bedingung versehen, die die Zeile erfüllen soll. Die passende Bedingung könnte sehr flexibel sein, variierend von einem einfachen regulären Ausdruck zu einer Überprüfung des Inhalts einiger Felder mit der Möglichkeit von Gruppenbedingungen mit den geeigneten logischen Operatoren.
Wie jede andere Programmiersprache implementiert auch awk alle notwendigen Kontollstrukturen sowie einen Satz von Operatoren und vordefinierten Funktionen, um mit Zahlen und Zeichenketten zu arbeiten.
Es ist aber natürlich möglich, benutzerdefinierte Funktionen mit dem Schlüsselwort function zu definieren. Außer den gewöhnlichen Skalarvariablen ist awk auch in der Lage, Felder verschiedener Größe zu handhaben.
Wie es in jeder Programmiersprache vorkommt, gibt es einige oft benutzte
Funktionen und es ist unbequem, Codestücke immer mit cut & paste rüberzukopieren.
Das ist der Grund, warum Bibliotheken existieren. Mit der GNU
Version von awk
ist es möglich, sie in ein
awk
Programm einzubinden. Dies ist jedoch ein Ausblick zu Dingen,
die möglich sind, aber außerhalb der Reichweite dieses Artikels liegen.
AWK ist sehr passend für die Zwecke, für die es entworfen wurde: Einlesen von Daten Zeile für Zeile und auf den Zeichenketten und Mustern dieser Zeilen operieren.
Dateien wie /etc/password
stellen sich als ideal für das
Reformatieren und Bearbeiten mit AWK heraus. AWK ist unschätzbar für solche
Aufgaben.
Natürlich ist AWK nicht allein. Perl ist ein starker Konkurrent, aber es ist trotzdem hilfreich, einige AWK Tricks zu kennen.
Diese Art von einfachen Grundfunktionen ist nicht gut dokumentiert, aber du findest etwas, wenn du dich umschaust.
man awk
Normalerweise erwähnen alle Bücher über Unix diesen Befehl, aber nur einige behandeln ihn ausführlich. Das beste, was man machen kann, ist, in jedem Buch, das einem in die Hände fällt, danach zu suchen. Man weiß nie, wo man unerwartet nützliche Informationen finden kann.