Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
Shell-Programmierung von Jürgen Wolf
Einführung, Praxis, Referenz
Buch: Shell-Programmierung

Shell-Programmierung
782 S., mit CD, 44,90 Euro
Rheinwerk Computing
ISBN 3-89842-683-1
gp Kapitel 13 awk-Programmierung
  gp 13.1 Einführung und Grundlagen von awk
    gp 13.1.1 History und Versionen von awk
    gp 13.1.2 Die Funktionsweise von awk
  gp 13.2 Aufruf von awk-Programmen
    gp 13.2.1 Grundlegender Aufbau eines awk-Kommandos
    gp 13.2.2 Die Kommandozeilen-Optionen von awk
    gp 13.2.3 awk aus der Kommandozeile aufrufen
    gp 13.2.4 awk in Shellscripts aufrufen
    gp 13.2.5 awk als eigenes Script ausführen
  gp 13.3 Grundlegende awk-Programme und -Elemente
    gp 13.3.1 Ausgabe von Zeilen und Zeilennummern
    gp 13.3.2 Felder
  gp 13.4 Muster (bzw. Adressen) von awk-Scripts
    gp 13.4.1 Zeichenkettenvergleiche
    gp 13.4.2 Vergleichsausdrücke
    gp 13.4.3 Reguläre Ausdrücke
    gp 13.4.4 Zusammengesetzte Ausdrücke
    gp 13.4.5 BEGIN und END
  gp 13.5 Die Komponenten von awk-Scripts
    gp 13.5.1 Variablen
    gp 13.5.2 Arrays
    gp 13.5.3 Operatoren
    gp 13.5.4 Kontrollstrukturen
  gp 13.6 Funktionen
    gp 13.6.1 Mathematische Funktionen
    gp 13.6.2 Funktionen für Zeichenketten
    gp 13.6.3 Funktionen für die Zeit
    gp 13.6.4 Systemfunktionen
    gp 13.6.5 Ausgabefunktionen
    gp 13.6.6 Eingabefunktion
    gp 13.6.7 Benutzerdefinierte Funktionen
  gp 13.7 Empfehlung


Rheinwerk Computing

13.4 Muster (bzw. Adressen) von awk-Scriptdowntop

Wie schon bei sed können Sie mit awk Adressen bzw. Muster benennen, die als Suchkriterium angegeben werden. Ein Muster dient auch hier dazu, den Programmfluss von awk zu steuern. Stimmt der Inhalt mit der zu bearbeitenden Zeile mit dem angegebenen Muster überein, wird der entsprechende Aktionsteil ausgeführt. Um solche Muster in awk darzustellen, haben Sie mehrere Möglichkeiten. Welche dies sind und wie Sie diese verwenden können, erfahren Sie in den folgenden Unterabschnitten.


Rheinwerk Computing

13.4.1 Zeichenkettenvergleiche  downtop

Am einfachsten und gleichzeitig auch häufigsten werden Muster bei Zeichenvergleichen eingesetzt. Diese Verwendung sieht folgendermaßen aus:

you@host > awk '/Jürgen Wolf/'
Hallo Jürgen
Hallo Wolf
Mein Name ist Jürgen Wolf
Mein Name ist Jürgen Wolf
(Strg)+(D)

Hier wird nur die Eingabe von der Tastatur wiederholt, wenn in $0 die Textfolge »Jürgen Wolf« enthalten ist. Auf eine Datei wird der Zeichenkettenvergleich ähnlich ausgeführt:

you@host > awk '/Samir/' mrolympia.dat
Samir Bannout Libanon 1983

Hier erhält awk die Eingabezeile aus der Datei mrolympia.dat, sucht nach einem Muster und gibt gegebenenfalls die komplette Zeile der Fundstelle auf den Bildschirm aus. Hier fällt außerdem auf, dass awk auch ohne den Aktionsteil und den Befehl print die komplette Zeile auf dem Bildschirm ausgibt. Natürlich werden auch Teil-Textfolgen gefunden, sprich es müssen nicht zwangsläufig ganze Wörter sein:

you@host > awk '/ie/' mrolympia.dat
Franco Columbu Argentinien 1976 1981
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Rheinwerk Computing

13.4.2 Vergleichsausdrücke  downtop

awk bietet auch Vergleichsausdrücke in den Mustern an. Hierzu werden die in vielen Programmiersprachen üblichen Vergleichsoperatoren verwendet. Ist ein Vergleichsausdruck (also das Muster) wahr, wird der entsprechende Aktionsteil ausgeführt. In der folgenden Tabelle finden Sie alle Vergleichsoperatoren aufgelistet.


Tabelle 13.3   Vergleichsoperatoren von awk

Operator Bedeutung Beispiel
< Kleiner als x < y
<= Kleiner als oder gleich x <= y
== Gleichheit x == y
!= Ungleichheit x != y
>= Größer als oder gleich x >= y
> Größer als x > y
~ Mustervergleich x ~ /y/
!~ Negierter Mustervergleich x !~ /y/

Ein Vergleichsausdruck lässt sich dabei sowohl auf Zahlen als auch auf Zeichenketten anwenden. Ein Beispiel:

you@host > awk '$4 > 1990' mrolympia.dat
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hier geben Sie alle Teilnehmer aus, die Ihren ersten Wettkampf nach 1990 gewonnen haben. Es werden also sämtliche Zeilen ausgegeben, bei denen der Wert des vierten Feldes größer als 1990 ist. Ein weiteres Beispiel:

you@host > awk '$2 < "H"' mrolympia.dat
Franco Columbu Argentinien 1976 1981
Chris Dickerson USA 1982
Samir Bannout Libanon 1983
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hiermit werden alle Werte (Namen) der zweiten Spalte ausgegeben, deren Anfangsbuchstabe kleiner als »H« ist. Gemeint ist hier der ASCII-Wert! »C« ist zum Beispiel kleiner als »H« in der ASCII-Tabelle usw. Natürlich lässt sich dies auch auf eine ganze Zeichenkette anwenden:

you@host > awk '$1 > "Dorian" ' mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
Franco Columbu Argentinien 1976 1981
Samir Bannout Libanon 1983
Lee Haney USA 1984 1985 1986 1987 1988 1989 1990 1991
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hier werden alle Vornamen ausgegeben, deren Name im ersten Feld größer als (heißt: nicht länger) der von »Dorian« ist – auch wenn es in diesem Beispiel wenig Sinn macht. Interessant ist auch der Vergleichsoperator für Mustervergleiche, beispielsweise:

you@host > awk '$3 ~ /USA/ ' mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
Chris Dickerson USA 1982
Lee Haney USA 1984 1985 1986 1987 1988 1989 1990 1991
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hier werden alle Zeilen selektiert, in denen sich in der dritten Spalte das Muster »USA« befindet. Damit können Sie das exakte Vorkommen eines Musters in der entsprechenden Spalte bestimmen. Natürlich können Sie dies auch negieren (verneinen):

you@host > awk '$3 !~ /USA/ ' mrolympia.dat
Arnold Schwarzenegger Österreich 1970 1971 1972 1973 1974 1975
Franco Columbu Argentinien 1976 1981
Samir Bannout Libanon 1983
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997

Jetzt werden alle Zeilen ausgegeben, bei denen sich in der dritten Spalte nicht das Muster »USA« befindet.

Wissen Sie jetzt zum Beispiel, dass 1988 ein US-Amerikaner den Wettkampf gewonnen hat, aber nicht genau welcher, formulieren Sie dies mit awk folgendermaßen:

you@host > awk '$3 ~ /USA/ && /1988/' mrolympia.dat
Lee Haney USA 1984 1985 1986 1987 1988 1989 1990 1991

Damit wählen Sie die Zeile(n) aus, bei denen sich in der dritten Spalte das Muster »USA« befindet und irgendwo in der Zeile das Jahr 1988. Hier wurde mit dem && eine logische UND-Verknüpfung vorgenommen, worauf noch in einem extra Abschnitt eingegangen wird.

Wollen Sie nur die ersten fünf Zeilen einer Datei ausgeben lassen? Nichts ist leichter als das:

you@host > awk 'NR <=5' mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
Arnold Schwarzenegger Österreich 1970 1971 1972 1973 1974 1975
Franco Columbu Argentinien 1976 1981
Chris Dickerson USA 1982

Wenn Sie jeden Datensatz ausgeben lassen wollen, der weniger als 5 Felder enthält, dann machen Sie dies mit awk so:

you@host > awk 'NF < 5' mrolympia.dat
Chris Dickerson USA 1982
Samir Bannout Libanon 1983

Rheinwerk Computing

13.4.3 Reguläre Ausdrücke  downtop

Natürlich stehen Ihnen auch mit awk wieder die regulären Ausdrücke zur Verfügung, mit denen Sie Ihre Muster formulieren können. Hierzu ein kurzer Überblick zu den Metazeichen und ihren Bedeutungen, die Sie für reguläre Ausdrücke mit awk heranziehen können. Da die regulären Ausdrücke ja bereits einige Mal behandelt wurden, finden Sie hier allerdings nur einen kurzen Überblick, da die meisten Zeichen auch hier ihre bereits bekannte Funktion erfüllen.


Tabelle 13.4   Metazeichen für reguläre Ausdrücke in awk

Zeichen Bedeutung
^ Anfang einer Zeile oder Zeichenkette
$ Ende einer Zeile oder Zeichenkette
. Jedes Zeichen außer einem Zeilenumbruch
* Null, eines oder mehrere Vorkommen
[] Ein Zeichen aus der Menge enthalten
[^] Kein Zeichen aus der Menge enthalten
re1|re2 ODER; entweder Muster re1 oder re2 enthalten
re1&re2 UND; Muster re1 und Muster re2 enthalten
+ Eines oder mehrere Vorkommen
(ab)+ Mindestens ein Auftreten der Menge »ab«
? Null oder einmaliges Vorkommen
& Enthält das Suchmuster des Ersetzungsstrings

Auch zur Verwendung muss wohl nicht mehr allzu viel geschrieben werden, da Sie ja bereits zuhauf Beispiele in sed gesehen haben. Trotzdem hierzu einige Beispiele mit regulären Ausdrücken.

you@host > awk '/[0–9]+/ { print $0 ": eine Zahl" } \
> /[A-Za-z]+/ { print $0 ": ein Wort" }'
Hallo
Hallo: ein Wort
1234
1234: eine Zahl

Hier können Sie ermitteln, ob es sich bei der Eingabe von der Tastatur um ein Wort oder um eine Zahl handelt. Allerdings funktioniert dieses Script nur so lange, wie es in einer Umgebung eingesetzt wird, in der sich derselbe Zeichensatz befindet wie beim Entwickler. Um hier wirklich Kompatibilität zu erreichen, sollten Sie in einem solchen Fall vordefinierte Zeichenklassen verwenden (siehe Abschnitt 1.10.6, Tabelle 1.5). In der Praxis sollte diese Zeile daher folgendermaßen aussehen:

you@host > awk '/[[:digit:]]+/ { print $0 ": eine Zahl" } \
> /[[:alpha:]]+/ { print $0 ": ein Wort" }'

Im Zusammenhang mit den regulären Ausdrücken wird zudem häufig der Match-Operator (~) eingesetzt, womit Sie ermitteln, ob ein bestimmtes Feld in einer Zeile einem bestimmten Muster (regulären Ausdruck) entspricht.

you@host > awk '$1 ~ /^[A-D]/' mrolympia.dat
Arnold Schwarzenegger Österreich 1970 1971 1972 1973 1974 1975
Chris Dickerson USA 1982
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997

Hier werden zum Beispiel alle Zeilen ausgegeben, bei denen in der ersten Spalte der erste Buchstabe in der Zeile ein »A«, »B«, »C« oder »D« ist. Das Gegenteil erreichen Sie mit:

you@host > awk '$1 ~ /^[^A-D]/' mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
Franco Columbu Argentinien 1976 1981
...

Hierbei lässt sich allerdings auch erkennen, dass reguläre Ausdrücke in Verbindung mit awk zum einen sehr leistungsstark sind, aber auch sehr »kryptisch« werden können. Hier zu Rezept-Zwecken einige weitere awk-Beispiele mit regulären Ausdrücken.

awk '$0 !~ /^$/' datei.dat

Damit »löschen« Sie alle leeren Zeilen in einer Datei (datei.dat) (»Löschen« trifft die Sache eigentlich nicht genau, vielmehr löscht man die Zeilen nicht in einer Datei, sondern gibt alles, was nicht leer ist, auf dem Bildschirm aus). $0 steht für die komplette Zeile und schließt alle Muster aus (!~), die eine leere Zeile enthalten. ^ steht für den Anfang und $ für das Ende einer Zeile.

Nächstes Beispiel:

you@host > awk '$2 ~ /^[CD]/ { print $3 }' mrolympia.dat
Argentinien
USA
USA

Hier suchen Sie nach allen Zeilen, bei denen sich in der zweiten Spalte ein Wort befindet, das mit den Buchstaben »C« oder »D« beginnt, und geben bei Erfolg das dritte Feld der Zeile aus.

Noch ein Beispiel:

you@host > awk '$3 ~ /Argentinien|Libanon/' mrolympia.dat
Franco Columbu Argentinien 1976 1981
Samir Bannout Libanon 1983

Hier werden alle Zeilen ausgegeben, die in der dritten Spalte die Textfolge »Argentinien« oder »Libanon« enthalten.


Rheinwerk Computing

13.4.4 Zusammengesetzte Ausdrücke  downtop

Es ist ebenso möglich, mehrere Ausdrücke zu einem Ausdruck zusammenzusetzen. Hierzu werden die üblichen Verknüpfungen UND (&&) und ODER (||) zwischen den Ausdrücken verwendet. So gilt bei einer UND-Verknüpfung von zwei Ausdrücken, dass der Aktionsteil bzw. der Ausdruck wahr ist, wenn beide Ausdrücke zutreffen, zum Beispiel:

you@host > awk '$3 ~ /USA/ && $2 ~ /Dickerson/' mrolympia.dat
Chris Dickerson USA 1982

Hier wird nur die Zeile ausgegeben, welche die Textfolge »USA« in der dritten Spalte als Ausdruck UND die Textfolge »Dickerson« in der zweiten Spalte enthält. Wird keine Zeile gefunden, die mit beiden Ausdrücken übereinstimmt, wird nichts ausgegeben.

Auf der anderen Seite können Sie mit einer ODER-Verknüpfung dafür sorgen, dass nur einer der Ausdrücke zutreffen muss:

you@host > awk '$3 ~ /USA/ || $2 ~ /Yates/' mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
Chris Dickerson USA 1982
Lee Haney USA 1984 1985 1986 1987 1988 1989 1990 1991
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hierbei werden alle Zeilen ausgegeben, bei denen das Muster »USA« in der dritten Spalte ODER das Muster »Yates« in der zweiten Spalte enthalten ist.

Natürlich lassen sich mehr als nur zwei Ausdrücke verknüpfen und auch die ODER- bzw. UND-Verknüpfungen mischen. Doch es gilt, nicht zu übertreiben, um den Überblick zu wahren.


Rheinwerk Computing

13.4.5 BEGIN und END  toptop

Mit BEGIN und END haben Sie zwei Muster, die vollkommend unabhängig von der Eingabezeile sind. Man kann sich dies wie bei einer Schleife vorstellen. Alles, was sich vor dem eigentlichen awk-Script noch abspielen soll, können Sie in einen BEGIN-Block schreiben:

BEGIN { Aktionsteil }

Hier können Sie bspw. eine Vorverarbeitung für den eigentlichen Hauptteil von awk festlegen. Allerdings ist damit nicht die Vorverarbeitung der Eingabezeile gemeint, da diese zu dem Zeitpunkt, wenn der BEGIN-Block ausgeführt wird, noch gar nicht eingelesen wurde. Der Aktionsteil kann genauso wie schon bei den »normalen« Mustern verwendet werden.

you@host > awk 'BEGIN { print "Vorname    Name       Land" }
> /USA/ { printf "%-10s %-10s %-5s\n", $1, $2, $3 }' \
> mrolympia.dat
Vorname    Name       Land
Larry      Scott      USA
Sergio     Oliva      USA
Chris      Dickerson  USA
Lee        Haney      USA
Ronnie     Coleman    USA

Wenn der BEGIN-Block vor der Verarbeitung der Eingabezeile ausgeführt wird, werden Sie sich sicherlich wohl denken können, dass sich der END-Block auf die Ausführung nach der Verarbeitung einer Eingabezeile bezieht. Wenn also alle Zeilen im Hauptblock ausgeführt wurden, kann am Ende noch zur Nachbearbeitung ein END-Block angehängt werden. Der END-Block wird ausgeführt, nachdem die letzte Zeile einer Datei abgearbeitet wurde oder bei Eingabe von der Tastatur (Strg)+(D) gedrückt wurde. Hier das Beispiel mit dem BEGIN-Block, erweitert um einen END-Block:

you@host > awk 'BEGIN { print "\nVorname    Name       Land" } \
> /USA/ { printf "%-10s %-10s %-5s\n", $1, $2, $3 } \
> END { print "---------Ende------------" } ' mrolympia.dat
Vorname    Name       Land
Larry      Scott      USA
Sergio     Oliva      USA
Chris      Dickerson  USA
Lee        Haney      USA
Ronnie     Coleman    USA
---------Ende------------

Hier wird zuerst der BEGIN-Block ausgeführt – im Beispiel nichts anderes als eine einfache Ausgabe auf dem Bildschirm. Anschließend werden die einzelnen Zeilen der Datei mrolympia.dat eingelesen und alle Zeilen mit dem Muster »USA« formatiert mit printf ausgegeben. Am Ende wird der END-Block ausgeführt, was hier nur eine einfache Textausgabe auf dem Bildschirm bedeutet. Ein END-Block setzt übrigens in keiner Weise einen BEGIN-Block voraus und kann immer auch nach einem Hauptteil verwendet werden – oder natürlich ganz alleine:

you@host > awk '{ print } END { print "Tschüssss..." }'
Hallo
Hallo
Welt
Welt
(Strg)+(D)
Tschüssss...

Hier liest awk Zeile für Zeile von der Kommandozeile ein und gibt diese im Hauptblock mit print zurück. Dies geht so lange, bis Sie (Strg)+(D) drücken. Nach dem Beenden mit (Strg)+(D) wird noch der END-Block ausgeführt.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

 << zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Shell-Programmierung
Shell-Programmierung
bestellen
 Buchtipps
Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-Programmierung


Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern