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.6 Funktionedowntop

awk ist ohnehin ein mächtiges Werkzeug. Doch mit den Funktionen, die awk Ihnen jetzt auch noch anbietet, können Sie awk noch mehr erweitern. Und sollten Ihnen die Funktionen, die awk mitliefert, nicht ausreichen, können Sie immer noch eigene benutzerdefinierte Funktionen hinzufügen.


Rheinwerk Computing

13.6.1 Mathematische Funktionen  downtop

Hier zunächst ein Überblick aller arithmetischen Funktionen, die Ihnen awk zur Verfügung stellt.


Tabelle 13.8   Mathematische Builtin-Funktionen von awk

Funktion Bedeutung
atan2(x,y) Arcustangens von x/y in Radian
cos(x) Liefert den Cosinus in Radian
exp(x) Exponentialfunktion
int(x) Abschneiden einer Zahl zu einer Ganzzahl
log(x) Natürlicher Logarithmus zur Basis e
rand() (Pseudo-)Zufallszahl zwischen 0 und 1
sin(x) Liefert den Sinus in Radian
sqrt(x) Quadratwurzel
srand(x) Setzt Startwert für Zufallszahlen. Bei keiner Angabe wird die aktuelle Zeit verwendet.

Zwar werden Sie als Systemadministrator seltener mit komplizierten arithmetischen Berechnungen konfrontiert sein, dennoch soll hier auf einige Funktionen eingegangen werden, mit denen Sie es als Nicht-Mathematiker häufiger zu tun bekommen. So zum Beispiel die Funktion int, womit Sie aus einer Gleitpunktzahl eine Ganzzahl machen, indem die Nachkommastellen abgeschnitten werden. Ein Beispiel:

you@host > awk 'END { print 30/4 }' datei
7,5
you@host > awk 'END { print int(30/4) }' datei
7

Neben dem Abschneiden von Gleitpunktzahlen benötigt man manchmal auch Zufallszahl. Hier bieten Ihnen die Funktionen rand und srand eine Möglichkeit an, solche zu erzeugen.

you@host > awk 'END { print rand() }' datei
0,237788

Hier haben Sie mit der Verwendung von rand eine Zufallszahl zwischen 0 und 1 erzeugt. Wenn Sie allerdings rand erneut aufrufen, ergibt sich dasselbe Bild:

you@host > awk 'END { print rand() }' datei
0,237788

Die Zufallsfunktion rand bezieht sich auf einen Startwert, mit dem sie eine (Pseudo-)Zufallszahl generiert. Diesen Startwert können Sie mit der Funktion srand verändern:

you@host > awk 'BEGIN { print srand() }; { print rand() }' datei
0,152827
you@host > awk 'BEGIN { print srand() }; { print rand() }' datei
0,828926

Mit der Funktion srand ohne Angabe eines Parameters wird jedes Mal zum Setzen eines neuen Startwerts für die Funktion rand die aktuelle Zeit verwendet. Dadurch ist die Verwendung von rand schon wesentlich effektiver und zufälliger (wenn auch nicht perfekt).


Rheinwerk Computing

13.6.2 Funktionen für Zeichenketten  downtop

Die Funktionen für Zeichenketten dürften die am häufigsten eingesetzten Funktionen für Sie als Shell-Programmierer sein. Oft werden Sie hierbei kein extra awk-Script schreiben, sondern die allseits beliebten Einzeiler verwenden. Trotzdem sollten Sie immer bedenken, dass wenn Sie awk-Einzeiler in Ihrem Shellscript in einer Schleife mehrmals aufrufen, dies jedes Mal den Start eines neuen (awk–)Prozesses bedeutet. Die Performance könnte darunter erheblich leiden. Bei häufigen awk-Aufrufen in Schleifen sollten Sie daher in Erwägung ziehen, ein awk-Script zu schreiben. Wie dies geht, haben Sie ja in diesem Kapitel erfahren. Die Syntax eines solchen Einzeilers in einem Shellscript sieht häufig wie folgt aus:

echo string | awk '{ print string_funktion($0) }'

oder

cat datei | awk '{ print string_funktion($0) }'

(Globale) Ersetzung mit sub und gsub

Die Syntax:

sub (regulärer_Ausdruck, Ersetzungs_String);
sub (regulärer_Ausdruck, Ersetzungs_String, Ziel_String)
gsub (regulärer_Ausdruck, Ersetzungs_String);
gsub (regulärer_Ausdruck, Ersetzungs_String, Ziel_String)

Mit beiden Funktionen wird das Auftreten von »regulärer_Ausdruck« durch »Ersetzungs_String« ersetzt. Wird kein »Ziel_String« mit angegeben, so wird $0 verwendet. Der Rückgabewert ist die Anzahl erfolgreicher Ersetzungen. Der Unterschied zwischen gsub und sub liegt darin, dass mit gsub (global substitution) eine globale Ersetzung und mit sub eine Ersetzung des ersten Vorkommens durchgeführt wird.

you@host > awk '{ gsub(/USA/, "Amerika"); print }' mrolympia.dat
Larry Scott Amerika 1965 1966
Sergio Oliva Amerika 1967 1968 1969
...

Hier werden alle Textfolgen »USA« der Datei mrolympia.dat durch »Amerika« ersetzt. Wollen Sie nur das erste Vorkommen ersetzen, so müssen Sie sub verwenden. Es kann aber nun sein, dass sich in einer Zeile mehrmals die Textfolge »USA« befindet, Sie aber nur eine bestimmte Spalte ersetzen wollen. Dann können Sie das dritte Argument von gsub bzw. sub verwenden:

you@host > awk '{ gsub(/USA/, "Amerika", $3); print }' mrolympia.dat
Larry Scott Amerika 1965 1966
Sergio Oliva Amerika 1967 1968 1969
...

Hier weisen Sie explizit an, dass nur wenn die dritte Spalte die Textfolge »USA« enthält, diese durch die Textfolge »Amerika« zu ersetzen ist.


Hinweis   Zu Demonstrationszwecken werden keine komplizierten regulären Ausdrücke verwendet, sondern immer einfache Textfolgen. Hier geht es lediglich um eine Funktionsbeschreibung der Zeichenketten-Funktionen von awk.


Position einer Zeichenkette ermitteln – index

Die Syntax:

index(string, substring)

Diese Funktion gibt die erste Position der Zeichenkette »substring« in »string« zurück. 0 wird zurückgegeben, wenn keine Übereinstimmung gefunden wurde. Folgendes Beispiel gibt alle Zeilen mit der Textfolge »USA« mitsamt ihren Positionen zurück:

you@host > awk '{ i=index($0, "USA"); if(i) print NR ":" i }' \
> mrolympia.dat
1:13
2:14
5:17
7:11
9:16

Länge einer Zeichenkette ermitteln – length

Die Syntax:

length(string)

Mit dieser Funktion können Sie die Länge der Zeichenkette »string« ermitteln. Nehmen Sie für »string« keine Angabe vor, wird $0 verwendet.

Folgendes Beispiel gibt die Länge der jeweils ersten Spalten einer jeden Zeile aus und das darauf folgende Beispiel, die Länge einer kompletten Zeile ($0):

you@host > awk '{ print NR ":" length($1) }' mrolympia.dat
1:5
2:6
3:6
...
you@host > awk '{ print NR ":" length }' mrolympia.dat
1:25
2:31
3:67
...

Suchen nach Muster – match

Die Syntax:

match(string, regulärer_Ausdruck)

Mit match suchen Sie nach dem Muster »regulärer_Ausdruck« in »string«. Wird ein entsprechender Ausdruck gefunden, wird die Position zurückgegeben, ansonsten bei erfolgloser Suche lautet der Rückgabewert 0. Die Startposition des gefundenen (Teil-)Strings »regulärer_Ausdruck« finden Sie in RSTART und die Länge des Teilstücks in RLENGTH. Ein Beispiel:

you@host > awk '{ i=match($0, "Yates"); \
> if(i) print NR, RSTART, RLENGTH }' mrolympia.dat
8 8 5

Hier wird nach der Zeichenfolge »Yates« gematcht und bei Erfolg werden die Zeile, die Position in der Zeile und die Länge zurückgegeben.

Zeichenkette zerlegen – split

Die Syntax:

split (string, array, feld_trenner)
split (string, array)

Mit dieser Funktion zerlegen Sie die Zeichenkette »string« und teilen die einzelnen Stücke in das Array »array« auf. Standardmäßig werden die einzelnen Zeichenketten anhand von FS (standardmäßig ein Leerzeichen) »zersplittet«. Allerdings können Sie dieses Verhalten optional über den dritten Parameter mit »feld_trenner« verändern. Als Rückgabewert erhalten Sie die höchste Indexnummer des erzeugten Arrays. Ein Beispiel zu dieser Funktion wurde bereits in Abschnitt 13.5.2 gegeben.

Eine Zeichenkette erzeugen – sprintf

Die Syntax:

string=sprintf(fmt, exprlist)

Mit sprintf erzeugen Sie eine Zeichenkette und liefern diese zurück. Der Formatstring »fmt« und die Argumente »exprlist« werden genauso verwendet wie bei printf für die Ausgabe. Ein einfaches Beispiel:

you@host > awk '{ \
> line=sprintf("%-10s\t%-15s\t%-15s", $1, $2, $3); print line }'\
> mrolympia.dat
Larry           Scott           USA
Sergio          Oliva           USA
Arnold          Schwarzenegger  Österreich
Franco          Columbu         Argentinien
...

Teilstück einer Zeichenkette zurückgegeben – substr

Die Syntax:

substr(string, start_position)
substr(string, start_position, länge)

Die Funktion gibt einen Teil einer Zeichenkette »string« ab der Position »start_position« entweder bis zur Länge »länge« oder bis zum Ende zurück.

you@host > awk '{ print substr($0, 5, 10)}' mrolympia.dat
y Scott US
io Oliva U
ld Schwarz
co Columbu
...

In diesem Beispiel wird (auch wenn es hier keinen Sinn macht) aus jeder Zeile der Datei mrolympia.dat eine Textfolge ab der Position 5 bis 10 ausgegeben (oder auch ausgeschnitten).

Groß- und Kleinbuchstaben – toupper und tolower

Die Syntax:

toupper(string)
tolower(string)

Mit der Funktion toupper werden alle Kleinbuchstaben in »string« in Großbuchstaben und mit tolower alle Großbuchstaben in Kleinbuchstaben umgewandelt. Ein Beispiel:

you@host > awk '{ print toupper($0)}' mrolympia.dat
LARRY SCOTT USA 1965 1966
SERGIO OLIVA USA 1967 1968 1969
ARNOLD SCHWARZENEGGER ÖSTERREICH 1970 1971 1972 1973 1974 1975
...
you@host > awk '{ print tolower($0)}' mrolympia.dat
larry scott usa 1965 1966
sergio oliva usa 1967 1968 1969
arnold schwarzenegger österreich 1970 1971 1972 1973 1974 1975
...

Rheinwerk Computing

13.6.3 Funktionen für die Zeit  downtop

In awk existieren auch zwei Funktionen für eine Zeitangabe: zum einen die Funktion systime (der UNIX-Timestamp), welche die aktuelle Tageszeit als Anzahl Sekunden zurückgibt, die seit dem 1.1.1970 vergangen sind. Zum anderen existiert noch die Funktion strftime, welche einen Zeitwert nach Maßangaben einer Formatanweisung (ähnlich wie bei dem Kommando date) formatiert. Diese Funktion ist außerdem der Funktion strftime() aus C nachgebildet und auch die Formatanweisungen haben dieselbe Bedeutung. Die Syntax zu strftime lautet:

strftime( format, timestamp );

Die möglichen Formatanweisungen von »format« finden Sie in der folgenden Tabelle. Den »timestamp« erhalten Sie aus dem Rückgabewert der Funktion systime. Hier zunächst die Formatanweisungen für strftime:


Tabelle 13.9   (Zeit-)Formatanweisungen für strftime

Format … wird ersetzt durch … Beispiel
%a Wochenname (gekürzt) Sat
%A Wochenname (ausgeschrieben) Saturday
%b Monatsname (gekürzt) Jan
%B Monatsname (ausgeschrieben) January
%c Entsprechende lokale Zeit- und Datumsdarstellung Sat Jan 22 22:22:22 MET 2003
%d Monatstag (1–31) 22
%H Stunde im 24-Stunden-Format (0–23) 23
%I Stunde im 12-Stunden-Format (1–12) 5
%j Tag des Jahres (1–366) 133
%m Monat (1–12) 5
%M Minute (0–59) 40
%p AM- oder PM-Zeitangabe; Indikator für das 12-Stunden-Format (USA) PM
%S Sekunden (0–69) 55
%U Wochennummer (0–53) (Sonntag als erster Tag der Woche) 33
%w Wochentag (0–6, Sonntag = 0) 3
%W Wochennummer (0–53) (Montag als erster Tag der Woche) 4
%x Lokale Datumsdarstellung 02/20/02
%X Lokale Zeitdarstellung 20:15:00
%y Jahreszahl (ohne Jahrhundertzahl 0–99) 01 (2001)
%Y Jahreszahl (mit Jahrhundertzahl YYYY) 2001
%Z, %z Zeitzone (gibt nichts aus, wenn Zeitzone unbekannt) MET
%% Prozentzeichen %

Hierzu ein simples Anwendungsbeispiel, welches alle Zeilen einer Datei auf dem Bildschirm und am Ende einen Zeitstempel ausgibt – eine einfache Demonstration der Funktionen systime und strftime:

#!/usr/bin/awk -f
#
# Programmname: timestamp.awk
BEGIN {
    now = systime()
    # macht eine Ausgabe ala date
    timestamp = strftime("%a %b %d %H:%M:%S %Z %Y", now)
}
{
   print
}
END {
   print timestamp
}

Das Script bei der Ausführung:

you@host > ./timestamp.awk mrolympia.dat
Larry Scott USA 1965 1966
Sergio Oliva USA 1967 1968 1969
...
...
Ronnie Coleman USA 1998 1999 2000 2001 2002 2003 2004
Fr Apr 15 07:48:35 CEST 2005

Rheinwerk Computing

13.6.4 Systemfunktionen  downtop

Sofern Sie reine awk-Scripts schreiben und awk nicht in ein Shellscript einbauen, aber einen UNIX-Befehl ausführen wollen, gibt es hierfür die Funktion system:

system("Befehl")

Damit können Sie jeden »Befehl« wie in der Kommandozeile ausführen. Sofern Sie die Ausgabe des Befehls abfangen wollen, müssen Sie getline (siehe Abschnitt 13.6.6) dazu verwenden:

"Befehl" | getline

Rheinwerk Computing

13.6.5 Ausgabefunktionen  downtop

Die eigentlichen Ausgabefunktionen print und printf haben Sie bereits kennen gelernt. Trotzdem soll hier noch eine Tabelle erstellt werden, worin Sie aufgelistet finden, wie Sie die Ausgabe anwenden können.


Tabelle 13.10   Mögliche print-Ausgaben

Verwendung Bedeutung
print Ausgabe der aktuellen Zeile (Datensatz); gleichwertig mit print $0.
print /reguläerer Ausdruck/ Hier können Sie bspw. testen, ob der Ausdruck in der entsprechenden Zeile zutrifft. Trifft der Ausdruck nicht zu, wird 0, ansonsten 1 zurückgegeben. Bspw.: awk '{ print /USA/ }' mrolympia.dat gibt in jeder Zeile, in der die Textfolge »USA« enthalten ist, 1 und sonst 0 zurück.
print Ausdrucksliste Ausgabe aller in »Ausdrucksliste« angegebenen Werte. Hierbei können Konstanten, berechnete Werte, Variablen- oder Feldwerte enthalten sein.
print Ausdrucksliste > datei Die Ausgabe aller in »Ausdrucksliste« angegebenen Werte wird in datei geschrieben. Dabei kann es sich durchaus um einen berechneten Wert handeln.
print Ausdrucksliste >> datei Wie eben, nur dass hierbei die Ausgabe aller in »Ausdrucksliste« enthaltenen Werte ans Ende von datei gehängt wird.

Für printf gilt das Gleiche, nur dass die Ausgabe formatiert erfolgt.


Rheinwerk Computing

13.6.6 Eingabefunktion  downtop

Der eine oder andere mag jetzt ganz verwundert sein, aber awk unterstützt auch eine Eingabefunktion mit getline. getline ist ein sehr vielseitiges Kommando. Diese Funktion liefert im Fall eines Fehlers –1, bei Dateiende oder (Strg)+(D) 0 und bei erfolgreichem Lesen 1 zurück. Sie liest eine Zeile von der Eingabezeile, was stdin oder eine Datei sein kann, und speichert diese entweder in $0 oder in einer separat angegebenen Variablen.


Tabelle 13.11   Die getline-Eingabefunktion

Verwendung Bedeutung
getline Verwenden Sie getline ohne Argumente, wird vom aktuellen Eingabekanal der nächste Datensatz (Zeile) eingelesen und in $0 gespeichert.
getline var Liest die nächste Zeile vom aktuellen Eingabekanal und speichert diese Zeile in »var«. Wichtig, NR und FNR werden hochgezählt, aber NF wird nicht belegt, weil hier keine Auftrennung in Worten (Feldern) erfolgt!
getline < datei Liest die nächste Zeile von einer Datei, welche geöffnet wird und am Ende mittels close() selbst geschlossen werden muss! Die Zeile befindet sich in $0.
getline var < datei Liest die nächste Zeile von einer Datei, welche geöffnet wird und am Ende mittels close() selbst geschlossen werden muss, in die Variable »var« ein. Hierbei werden allerdings NF, NR und FNR nicht verändert!
string | getline Liest die nächste Zeile von der Pipe (hier dem String »string«) ein. Die eingelesene Zeile wird in $0 gespeichert.
"kommando" | getline var Hier wird die nächste Zeile von einem Kommando eingelesen und die eingelesene Zeile befindet sich in »var«.

Bei der Verwendung von getline war auch die Rede von der Funktion close, mit der Sie eine Datei oder eine geöffnete Pipe wieder schließen müssen.

close(Dateinamen)

Der Dateiname kann hierbei als eine Stringkonstante vorliegen oder eine Variable sein.


Hinweis   Möglicherweise ist dies etwas verwirrend, weil in awk die Datei zwar automatisch geöffnet wird, aber sobald man mit getline etwas daraus liest, diese wieder von Hand mit close geschlossen werden soll. Gerade wenn man andere Programmiersprachen verwendet, kennt man doch die Logik, ein Programm manuell zu öffnen und diese auch wieder manuell zu schließen.


Hierzu ein einfaches Beispiel. Im Script werden Sie gefragt, wonach und in welcher Datei Sie suchen wollen. Mit getline lesen Sie dann Zeile für Zeile in die while-Schleife ein. Anschließend wird die Zeile mit dem eingegebenen Suchstring verglichen und bei Übereinstimmung ausgegeben.

#!/usr/bin/awk -f
#
# Programmname: search.awk
BEGIN {
   # Suchstring eingeben
   print "Wonach suchen Sie : "
   getline searchstring
   # Datei zum Suchen eingeben
   print "In welcher Datei  : "
   getline file
   # Zeilenweise aus der Datei lesen
   while( getline < file ) {
      if($0 ~ searchstring) {
         print
      }
   }
   close(file)
}

Hinweis   In der Praxis sollten Sie natürlich überprüfen, ob die Datei zum Öffnen überhaupt existiert oder/und lesbar ist und gegebenenfalls abbrechen.


Das Script bei der Ausführung:

you@host > ./search.awk
Wonach suchen Sie : USA
In welcher Datei  : 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
you@host > ./search.awk
Wonach suchen Sie : ien
In welcher Datei  : mrolympia.dat
Franco Columbu Argentinien 1976 1981
Dorian Yates Grossbritannien 1992 1993 1994 1995 1996 1997
you@host > ./search.awk
Wonach suchen Sie : Samir
In welcher Datei  : mrolympia.dat
Samir Bannout Libanon 1983

Hier soll auch noch ein weiteres gängiges und mächtiges Feature von getline vorgestellt werden, und zwar die Möglichkeit, ein (Linux-/UNIX-)Kommando nach getline zu »pipen«. Das folgende Script gibt die größte Datei aus. Die Größe einer Datei finden Sie mit ls –l in der fünften Spalte.

#!/usr/bin/awk -f
#
# Programmname: bigfile.awk
{
   my_ls="/bin/ls -ld '" quoting($0) "' 2>/dev/null"
   if( my_ls | getline ) {
      if( $5 > filesize ) {
         filename=$8
         filesize=$5
      }
   }
   close(my_ls)
}
END {
   if( filename )
     print "Größte Datei ist " filename " mit " filesize " Bytes"
   else
      print "Konnte keine größte Datei ermitteln?!?"
}
function quoting(s, n) {
   n=s
   gsub(/'/, "'\"'\"'", n)
   return n
}

Das Script bei der Ausführung:

you@host > find $HOME -print | ./bigfile.awk
Größte Datei ist ~/Desktop/Trash/Trailer.mpg mit 91887620 Byte

Im Script wurde auch eine Funktion zum Schutz für Dateien mit einfachen Anführungszeichen (Single Quotes) verwendet. Mehr zu den selbst definierten Funktionen erfahren Sie gleich.


Rheinwerk Computing

13.6.7 Benutzerdefinierte Funktionen  toptop

Als Programmierer von Shellscripts dürften Sie mit dem awk-Wissen, das Sie jetzt haben, mehr als zufrieden sein. Aber neben der Verwendung von Builtin-Funktionen von awk haben Sie außerdem noch die Möglichkeit, eigenen Funktionen zu schreiben. Daher hier noch eine kurze Beschreibung, wie Sie auch dies realisieren können. Der Ort einer Funktionsdefinition ist nicht so wichtig, obgleich es sich eingebürgert hat, diese am Ende des Scripts zu definieren.

function functions_name( parameter ) {
   # Anweisungen
}

Dem Schlüsselwort function, welches Sie immer verwenden müssen, folgt der Funktionsname. Erlaubt sind hier alle Kombinationen aus Buchstaben, Ziffern und einem Unterstrich – einzig am Anfang darf keine Ziffer stehen. Variablen und Funktion dürfen in einem Script allerdings nicht denselben Namen haben. Als Argumente können Sie einer Funktion beliebig viele oder auch gar keine Parameter angeben. Mehrere Argumente werden mit einem Komma getrennt. Die Anweisungen einer Funktion werden zwischen geschweiften Klammern (dem Anweisungsblock) zusammengefasst.

Zum Aufruf einer Funktion müssen Sie den Funktionsnamen gefolgt von runden Klammern und eventuell den einzelnen Parametern angeben. Beachten Sie außerdem, dass sich zwischen dem Funktionsnamen und der sich öffnenden Klammer kein Leerzeichen befinden darf. Werden weniger Parameter als in der Funktionsdefinition definiert angegeben, so führt dies nicht zu einem Fehler. Nicht angegebene Parameter werden – abhängig vom Kontext – als 0 oder eine leere Zeichenkette interpretiert.

Anders sieht dies allerdings aus, wenn Sie einer Funktion einen Parameter übergeben, obwohl in der Funktionsdefinition keinerlei Argumente enthalten sind. Dann wird Ihnen awk das Script mit einer Fehlermeldung abbrechen.

Alle Variablen einer Funktion sind global, abgesehen von den Variablen in den runden Klammern. Deren Gültigkeitsbereich ist nur auf die Funktion allein beschränkt.

Um Werte aus einer Funktion zurückzugeben, wird auch hierbei der return-Befehl gefolgt vom Wert verwendet. Beispielsweise:

function functions_name( parameter ) {
   # Anweisungen
   ...
   return Wert
}

Mehrere Werte können Sie auch hier, wie in der Shell, zu einem String zusammenfassen und im Hauptteil wieder splitten:

function functions_name( parameter ) {
   # Anweisungen
   ...
   return Wert1 " " Wert2 " " Wert3
}
...
ret=functions_name( param )
split(ret, array)
...
print array[1]

Hier konnten Sie auch gleich sehen, wie Sie im Hauptteil den Rückgabewert auffangen können.

Die Übergabe von Variablen erfolgt in der Regel »by-value«, sprich: Die Werte des Funktionsaufrufs werden in die Argumente der Funktion kopiert, sodass jede Veränderung des Werts nur in der Funktion gültig ist. Anders hingegen werden Arrays behandelt, diese werden »by-reference«, also als Speicheradresse auf den ersten Wert des Arrays übergeben. Dies erscheint sinnvoll, denn müsste ein Array mit mehreren hundert Einträgen erst kopiert werden, wäre ein Funktionsaufruf wohl eine ziemliche Bremse. Somit bezieht sich allerdings eine Veränderung des Arrays in der Funktion auch auf das Original.

Hierzu ein einfaches Beispiel mit einer selbst definierten Funktion:

#!/usr/bin/awk -f
#
# Programmname: FILEprint.awk
{
  FILEprint($0)
}
function FILEprint( line ) {
   if(length(line) == 0)
      return "Leerer String"
   else
      print FILENAME "(" NR ") : " line
}

Das Script bei der Ausführung:

you@host > ./FILEprint.awk mrolympia.dat
mrolympia.dat(1) : Larry Scott USA 1965 1966
mrolympia.dat(2) : Sergio Oliva USA 1967 1968 1969
mrolympia.dat(3) : Arnold Schwarzenegger Österreich 1970 1971 1972
...
...

Hier haben Sie eine einfache benutzerdefinierte print-Funktion, welche am Anfang einer Zeile jeweils den Dateinamen und die Zeilennummer mit ausgibt.



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