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.3 Grundlegende awk-Programme und -Elementdowntop

Wenn man noch nie einen Baum gepflanzt hat, wird man keine ganzen Wälder anlegen. Daher folgen hier zunächst die grundlegenden Elemente bzw. die einfachen Anwendungen von awk. Was man für awk zuallererst benötigt, das ist die Ausgabe von Zeilen und alles, was mit den Zeilen zu tun hat, die Verwendung von Feldern (bzw. Wörtern) und die formatierte Ausgabe bzw. die Ausgabe in einer Datei.


Rheinwerk Computing

13.3.1 Ausgabe von Zeilen und Zeilennummern  downtop

Am besten fängt man mit dem Einfachsten an:

you@host > awk '{print}'
Ein Test
Ein Test
Noch einer
Noch einer

Dieser Einzeiler macht nichts anderes, als alle Eingaben, die Sie mit (ENTER) abgeschlossen haben, wieder auf dem Bildschirm auszugeben. Und zwar so lange, bis Sie die Tastenkombination (Strg)+(D) (für EOF) drücken. Im Prinzip funktioniert dies wie bei einem einfachen cat. Schreiben Sie jetzt einen Dateinamen hinter dem awk-Programm

you@host > awk '{print}' mrolympia.dat
...

erhält awk seine Eingabe nicht mehr von der Tastatur, sondern entnimmt diese zeilenweise der Datei. Aber, so ein einfaches cat ist awk auch wieder nicht. Wollen Sie, dass awk bestimmte Wörter von der Tastatur herausfiltert, können Sie hierzu ein Muster verwenden:

you@host > awk '!/mist/ {print}'
Die ist kein Mist
Die ist kein Mist
Aber hier ist ein mist!
Ende
Ende

Hiermit wird jede Zeile, welche die Textfolge »mist« enthält, nicht ausgegeben.

Benötigen Sie die laufende Zeilennummer, steht Ihnen die awk-interne Variable NR zur Verfügung, die sich immer die aktuelle Nummer der Eingabezeile merkt.

you@host > awk '{print NR " : " $0}' mrolympia.dat
1 : Larry Scott USA 1965 1966
2 : Sergio Oliva USA 1967 1968 1969
...
...
8 : Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997
9 : Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004

Hiermit geben Sie die komplette Datei mrolympia.dat mitsamt der Zeilennummern auf dem Bildschirm aus. Eine weitere Besonderheit ist hier die Variable $0, die immer automatisch mit der gesamten eingelesenen Zeile belegt ist. Wollen Sie mit awk nach einem bestimmten Muster suchen und hierbei die entsprechende Zeile bei Übereinstimmung mit ausgeben, kann dies wie folgt realisiert werden:

you@host > awk '/Lee/ {print NR " : " $0}' mrolympia.dat
7 : Lee Haney USA 1984 1985 1986 1987 1988 1989 1990 1991

Es wird nach dem Muster »Lee« in der Datei mrolympia.dat gesucht und dann mitsamt der Zeilennummer ausgegeben.


Hinweis   Sie können mit awk noch einen Schritt weiter gehen, wenn Sie nicht die Variablen NR verwenden wollen, indem Sie die Zeilen selbst hochzählen. Hierzu müssen Sie nur eine extra Variable einsetzen und diese hochzählen: awk '{print ++i, " : " $0}' mrolympia.dat



Rheinwerk Computing

13.3.2 Felder  toptop

Die nächst kleinere Einheit nach den Zeilen sind die einzelnen Felder bzw. Wörter (abhängig von FS), in die jede Eingabezeile zerlegt wird. Allerdings ist es im Grunde falsch, bei awk von Wörtern zu sprechen, vielmehr sind es Felder. Standardmäßig werden die einzelnen Zeilen durch Leerzeichen und Tabulatorzeichen aufgetrennt und jeweils in eine eigene Variable gespeichert. Die Namen der Variablen entsprechen den Positionsparametern der Shell: $1, $2, $3 ...

Damit ist es ohne größeren Umweg möglich, einzelne Spalten aus einer Datei zu extrahieren, was u. a. auch ein Hauptanwendungsgebiet von awk ist. So können Sie z. B. ohne Probleme den Inhalt der Spalte 3 und 2 einer Datei ausgeben lassen:

you@host > awk '{print $3, $2}' mrolympia.dat
USA Scott
USA Oliva
Österreich Schwarzenegger
Argentinien Columbu
USA Dickerson
Libanon Bannout
USA Haney
Grossbritannien Yates
USA Coleman

Wollen Sie jetzt noch wissen, wie viele Titel einer der Teilnehmer gewonnen hat, können Sie die Variable NF (Number of Fields) verwenden:

you@host > awk '{print $3, $2, NF-3}' mrolympia.dat
USA Scott 2
USA Oliva 3
Österreich Schwarzenegger 7
Argentinien Columbu 2
USA Dickerson 1
Libanon Bannout 1
USA Haney 8
Grossbritannien Yates 6
USA Coleman 7

Hier wurde von NF der Wert 3 subtrahiert, da die ersten drei Spalten eine andere Bedeutung haben. Ich kann mir schon denken, wie die nächste Frage lauten könnte: Wie kann man dies jetzt noch nach der Anzahl von Titeln sortieren? Hier gibt es immer mehrere Wege – ich könnte folgenden anbieten:

you@host > awk '{print NF-3, $3, $2}' mrolympia.dat | sort -r
8 USA Haney
7 USA Coleman
7 Österreich Schwarzenegger
6 Grossbritannien Yates
3 USA Oliva
2 USA Scott
2 Argentinien Columbu
1 USA Dickerson
1 Libanon Bannout

Verwenden Sie NF mit einem Dollarzeichen davor ($NF), befindet sich darin immer das letzte Wort der Zeile. Das Vorletzte würden Sie mit $(NF–1) erreichen:

you@host > awk '{print $NF, $(NF-1)}' mrolympia.dat
1966 1965
1969 1968
1980 1975
1981 1976
1982 USA
1983 Libanon
1991 1990
1997 1996
2004 2003
you@host > awk '{print "Zeile " NR, "enhält " NF " Worte \
> (letztes Wort: " $NF "; vorletztes: " $(NF-1) ")"}' \
> mrolympia.dat
Zeile  1 enhält 5 Worte (letztes Wort: 1966 ; vorletztes: 1965)
Zeile  2 enhält 6 Worte (letztes Wort: 1969 ; vorletztes:1968
Zeile  3 enhält 10 Worte (letztes Wort: 1980 ; vorletztes: 1975)
Zeile  4 enhält 5 Worte (letztes Wort: 1981 ; vorletztes: 1976)
Zeile  5 enhält 4 Worte (letztes Wort: 1982 ; vorletztes: USA)
Zeile  6 enhält 4 Worte (letztes Wort: 1983 ; vorletztes:Libanon)
Zeile  7 enhält 11 Worte (letztes Wort: 1991 ; vorletztes: 1990)
Zeile  8 enhält 9 Worte (letztes Wort: 1997 ; vorletztes: 1996)
Zeile  9 enhält 10 Worte (letztes Wort: 2004 ; vorletztes: 2003)

Und natürlich gehört es zu den Grundlagen von Feldern, den Feldtrenner zu verändern. Dies kann über den Schalter –F oder in einem awk-Script über die Variable FS geschehen.

Formatierte Ausgabe und Dateiausgabe

Zur formatierten Ausgabe wurde bisher immer print verwendet, welches ähnlich wie echo in der Shell funktioniert. Da ja die einzelnen Felder anhand von Leerzeichen und Tabulatorzeichen getrennt werden, sollte es einleuchtend sein, dass bei der folgenden Ausgabe die Wörter nicht voneinander getrennt werden:

you@host > awk '{print $1 $2 }' mrolympia.dat
LarryScott
SergioOliva
...
...
DorianYates
RonnieColeman

Man kann entweder das Leerzeichen (oder auch ein anderes Zeichen bzw. andere Zeichenfolge) in Double Quotes eingeschlossen einfügen:

you@host > awk '{print $1 " " $2 }' mrolympia.dat

Oder aber man trennt die einzelnen Felder voneinander mit einem Komma:

you@host > awk '{print $1, $2 }' mrolympia.dat

Meistens reicht die Ausgabe von print. Aber auch hier haben Sie mit printf die Möglichkeit, Ihre Ausgabe erweitert zu formatieren. printf funktioniert hier genauso, wie es schon für die Shell beschrieben wurde, weshalb ich hier auf Tabellen mit den Typezeichen (s für String, d für Dezimal, f für Float usw.) verzichten kann. Bei Bedarf werfen Sie bitte einen Blick in Abschnitt 5.2.3. Gleiches gilt übrigens auch für die Escapesequenzen (alias Steuerzeichen) (siehe Tabelle 5.2). Einziger Unterschied im Gegensatz zum printf der Shell: Die Argumente am Ende müssen durch ein Komma getrennt werden. Ein einfaches Beispiel der formatierten Ausgabe mit printf:

you@host > awk ' \
> {printf "%-2d Titel\tLand: %-15s\tName: %-15s\n",NF-3,$3,$2}'\
> mrolympia.dat | sort -r
8  Titel        Land: USA               Name: Haney
7  Titel        Land: USA               Name: Coleman
7  Titel        Land: Österreich         Name: Schwarzenegger
6  Titel        Land: Grossbritannien   Name: Yates
3  Titel        Land: USA               Name: Oliva
2  Titel        Land: USA               Name: Scott
2  Titel        Land: Argentinien       Name: Columbu
1  Titel        Land: USA               Name: Dickerson
1  Titel        Land: Libanon           Name: Bannout

Zur Ausgabe in einer Datei wird für gewöhnlich eine Umlenkung verwendet:

you@host > awk \
> '{printf "%-2d Titel\tLand: %-15s\tName: %-15s\n",NF-3,$3,$2}'\
> mrolympia.dat > olymp.dat
you@host > cat olymp.dat
2  Titel        Land: USA               Name: Scott
3  Titel        Land: USA               Name: Oliva
7  Titel        Land: Österreich        Name: Schwarzenegger
2  Titel        Land: Argentinien       Name: Columbu
1  Titel        Land: USA               Name: Dickerson
1  Titel        Land: Libanon           Name: Bannout
8  Titel        Land: USA               Name: Haney
6  Titel        Land: Grossbritannien   Name: Yates
7  Titel        Land: USA               Name: Coleman

Es ist aber auch möglich, innerhalb von awk – im Aktionsteil – in eine Datei zu schreiben:

you@host > awk '/USA/{ print > "usa.dat"}' mrolympia.dat
you@host > cat usa.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

Im Beispiel wurden alle Zeilen mit einer Zeichenfolge »USA« in die Datei usa.dat geschrieben. Dies ist zum Beispiel sinnvoll, wenn Sie mehrere Muster-Aktions-Teile verwenden und nicht jede Ausgabe gleich in eine Datei geschrieben werden soll.

Um dem Ganzen die Krone aufzusetzen, folgendes Beispiel:

you@host > awk '$3 {print >> $3}' mrolympia.dat

Hier schreiben Sie für jedes Land den Inhalt des entsprechenden Eintrags ans Ende einer Datei mit dem entsprechenden Landesnamen. Genauer: Für jedes Land wird eine extra Datei angelegt, worin die einzelnen Teilnehmer immer ans Ende der Datei gehängt werden. Führen Sie das einmal in einer anderen Sprache mit einer Zeile durch.

you@host > ls -l
-rw-------  1 tot users      37 2005–04–11 15:34 Argentinien
-rw-------  1 tot users      58 2005–04–11 15:34 Grossbritannien
-rw-------  1 tot users      27 2005–04–11 15:34 Libanon
-rw-------  1 tot users     381 2005–04–08 07:32 mrolympia.dat
-rw-------  1 tot users      68 2005–04–11 15:34 Österreich
-rw-------  1 tot users     191 2005–04–11 15:34 USA
you@host > cat Libanon
Samir Bannout Libanon 1983
you@host > cat Österreich
Arnold Schwarzenegger Österreich 1970 1971 1972 1973 1974 1975

Natürlich können Sie das noch ganz anders erreichen:

you@host > awk '$3 {print $2, $1, $3 >> $3}' mrolympia.dat

Hier machen Sie das Gleiche, hängen jedoch nur den Inhalt der Felder $2, $3 und $1 an entsprechende Landesdatei. In Verbindung mit einer umfangreichen Datenbank ist das wirklich mächtig. Doch im Prinzip ist das noch gar nichts, awk ist bei richtiger Anwendung zu viel mehr im Stande.

Natürlich können Sie awk auch cat-ähnlich verwenden, um alle Eingaben von der Tastatur in eine Datei zu schreiben:

you@host > awk '{print > "atextfile"}'
Hallo Textdatei
Das steht drin
(Strg)+(D)
you@host > cat atextfile
Hallo Textdatei
Das steht drin


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