Beispiele mit awk: Eine kurze Einführung

ArticleCategory:[Article Category]

UNIX Basics

AuthorImage:[Author Photo]

[Photo of the Author]

TranslationInfo:[Author and translation history]

original in es Javier Palacios Bermejo 

es to en Javier Palacios Bermejo,Ruben Sotillo, Manuel Rodriguez

en to de Katja Socher

AboutTheAuthor:[Über den Autor]

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.

Abstract:[Abstract]

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.

ArticleIllustration:[Article head Illustration]

[Ilustration]

ArticleBody:[Article Body]

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.

Einführung in awk

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:


awk '  '{print $1}'   file


Einfach, nicht wahr? Diese einfache Aufgabe bedarf keiner komplexen Programmierung in C. Eine einzige Zeile mit AWK tut es.

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:

  1. Umbennen innerhalb des Namens:
    ls -1 *old* | awk '{print "mv "$1" "$1}' | sed s/old/new/2 | sh
    (klappt aber nicht in allen Fällen, wie z.B. in file_old_and_old)

  2. Entfernen nur von Dateien:
    ls -l * | grep -v drwx | awk '{print "rm "$9}' | sh
    oder nur mit awk:
    ls -l|awk '$1!~/^drwx/{print $9}'|xargs rm
    Paß auf, wenn du dies in deinem Home Verzeichnis ausprobierst. Wir löschen Dateien!

  3. Entfernen nur von Verzeichnissen
    ls -l | grep '^d' | awk '{print "rm -r "$9}' | sh
    oder
    ls -p | grep /$ | wk '{print "rm -r "$1}'
    oder nur mit awk:
    ls -l|awk '$1~/^d.*x/{print $9}'|xargs rm -r
    Paß auf, wenn du dies in deinem Home Verzeichnis ausprobierst. Wir löschen Verzeichnisse!

  4. Prozesse mit bestimmten Namen beenden (in diesem Bespiel beenden wir einen Prozeß namens netscape):
    kill `ps auxww | grep netscape | egrep -v grep | awk '{print $2}'`
    oder nur mit awk:
    ps auxww | awk '$0~/netscape/&&$0!~/awk/{print $2}' |xargs kill
    Es muß entsprechend an den ps Befehl angepaßt werden, je nach dem, auf was für einem Unixsystem man arbeitet. Grundsätzlich gilt : " Wenn der Prozeß netscape heißt und nicht 'grep netscape' (oder awk), dann drucke die pid"

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              --version

Anstatt 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=val ) können wir den Programmen einige Flexibilität verleihen.

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.

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 Problem

Ein 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 mit FS 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ösung

Ich 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.

Tiefer in AWK eintauchen

Arbeiten nur mit Zeilen, die bestimmte Bedingungen erfüllen

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.

Awk als Programmiersprache

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.

Einbinden von Bibliotheken

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.

Schlußbemerkungen

Sicherlich ist awk vielleicht nicht so mächtig wie andere Werkzeuge, die zu ähnlichen Zwecken entworfen wurden. Aber es hat den großen Vorteil, daß es möglich ist, in wirklich kurzer Zeit kleine Programme zu schreiben, die voll auf die eigenen Bedürfnisse zugeschnitten sind.

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.

Zusätzliche Informationen

Diese Art von einfachen Grundfunktionen ist nicht gut dokumentiert, aber du findest etwas, wenn du dich umschaust.

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.