awk - Eine Einführung

 
 URZ   Kontakt   Hotlines   Lageplan   webmail   URZ-Forum   Datennetz&Server-News   Meckerecke 

 

 

Vorwort

Aufruf

Struktur

Muster

Aktionen

Reguläre Ausdrücke

Konstanten

Variablen

Konkatenation

Vektoren

Funktionen

Operatoren

Ausgabe-Anweisungen

Eingabe mit getline

Standard-Files

printf und sprintf

Die Funktion system

Einsatzmöglichkeiten

awk-Programmbeispiel
 

    Vorwort

    awk bekam seinen Namen von den Entwicklern Aho, Weinberger und Kernighan .

    Grund für die Entwicklung war die Handhabung von sed, die den Entwicklern wohl nicht so recht zusagte.

    awk folgt den Ideen von sed, ist aber um viele Eigenschaften reicher. Es finden sich Kontroll-Strukturen, Variablen, Vektoren (assoziative und zahlenidizierte) und diverse Funktionen. awk wird nicht mehr als stream editor, sondern vielmehr als Programmiersprache angesehen, obwohl er auch als solcher fungieren kann.


  1. Aufruf
  2. awk wird ähnlich wie sed aufgerufen:
    awk 'awk-Programm' [Eingabedateien]
    awk -f 'Programm-Datei' [Eingabedateien]

    Es gibt noch eine ganze Reihe von Optionen, die zum Teil später beschrieben werden.

    Fehlt die Datei-Liste im Aufruf, so liest auch awk von stdin. Das Ergebnis der Programmausführung geht natürlich nach stdout.

    Rufen Sie awk wie in der ersten Zeile auf, so sind die "Hickerchen" keine syntaktische Forderung, aber in den meisten Fällen nötig, um andere Metazeichen innerhalb des awk-Programms, zu schützen.


  3. Struktur eines awk-Programms
  4. Ein awk-Programm besteht aus Folgen von:
    Muster {Aktion}
    Muster {Aktion}
    .
    .
    .
    function funktionsname (parameter) { anweisungen }
    .
    .
    .

    Das Verarbeitunsprinzip entspricht dem von sed. Es wird eine Zeile von der Eingabe gelesen und geprüft, ob diese von Muster adressiert wird. Ist dem so, wird die folgende Aktion ausgeführt. Wahlweise kann in einer Zeile entweder das Muster oder die Aktion weggelassen werden.

    Wird das Muster weggelassen, so wird die Aktion für jede Zeile ausgeführt. Hierbei dürfen die geschweiften Klammern aber nicht fehlen. Fehlt die Aktion, so wird die adressierte Zeile ausgegeben.

    Die Anweisungen werden durch neue Zeilen, oder durch Semikolon voneinander getrennt.


  5. Muster
  6. Die Muster dienen der Adressierung der Eingabezeile. Für die adressierte Zeile wird die zugehörige Aktion ausgeführt. Folgende Muster-Typen sind verfügbar:

    BEGIN
    Die Anweisung im Rumpf wird ausgeführt, bevor die erste Eingabezeile verarbeitet wird.
    END
    Die Anweisung im Rumpf wird ausgeführt, nachdem die letzte Eingabezeile verarbeitet wurde.
    ausdruck
    In Abhängigkeit des ausgewerteten Ausdrucks, der einen boolschen Wert liefert, wird die Aktion ausgeführt oder nicht.
    /regulärer Ausdruck/
    Wird die aktuelle Eingabezeile durch den regulären Ausdruck abgedeckt, so wird die Aktion ausgeführt.
    verbundene Muster
    Muster können sich aus mehreren Mustern zusammensetzen, die durch die Operatoren && (logisches UND), || (logisches ODER), ! (Negation) und ( ) (runde Klammern) verknüpft wurden. Die Aktion wird genau dann ausgeführt, wenn der Gesamt-Ausdruck einen wahren Wert liefert.
    Muster1,Muster2
    Die Aktion wird für den Bereich ausgeführt, der mit der Zeile beginnt, die durch Muster1 abgedeckt wird, und mit der Zeile endet, die durch Muster2 abgedeckt wird.

  7. Aktionen
  8. Während Sie mit Muster die Zeilen adressieren, legen Sie mit Aktion fest, was für diese Zeile zu tun ist. Eine Aktion kann sich aus vielen Anweisungen zusammensetzen. Dieses sind dann durch Semikola oder neue Zeilen voneinander zu trennen. Anweisungen in einer Aktion können sein:

    Ausdrücke mit Kostanten, Variablen, Zuweisungen, Funktionsaufrufe usw. break
    innerhalb einer do-, for- oder while-Schleife bewirkt den sofortigen Ausstieg aus dieser Schleife.
    continue
    innerhalb einer do-, for- oder while-Schleife wird der nächste Schleifendurchgang gestartet.
    delete
    löscht einen Index aus einem Assoziativen Vektor.
    (z.B.: delete vektor[index])
    do anweisung while (ausdruck)
    führt die anweisung aus, wertet den ausdruck aus und iteriert die anweisung gegebenenfalls.
    exit

    exit ausdruck
    bewirkt den Sprung zur END-Aktion. Ist diese nicht vorhanden, ist der Wert von ausdruck der Exit-Status des awk-Kommandos.
    for (ausdruck1; ausdruck2; ausdruck3) ausdruck
    ist eine andere Schreibweise für:
    ausdruck1; while (ausdruck2) {anweisung; ausdruck3}
    for (index in vektor) anweisung
    Der vektor wird über alle seine Elemente durchlaufen.
    if (ausdruck) anweisung
    wenn ausdruck der Wert trUE liefert, wird anweisung ausgeführt, andernfalls nicht.
    if (ausdruck) anweisung else anweisung
    analog der obigen if-Anweisung, nur wird im FALSE-Fall die anweisung nach else ausgeführt.

    Bei geschachtelten if-else-Anweisungen gehört das else zu dem letzten freien if.
    next
    veranlaßt das Lesen einer neuen Eingabezeile und startet das Programm erneut. Die BEGIN-Aktion wird hierbei aber nicht ausgeführt.
    while (ausdruck) anweisung
    solange ausdruck den Wert trUE liefert, führe anweisung aus.
    return

    return ausdruck
    innerhalb einer Funktion wird diese mit dem Wert von ausdruck verlassen.
    {anweisungen}
    überall dort, wo eine Anweisung stehen darf, dürfen die geschweiften Klammern einen Block einleiten. Innerhalb von geschweiften Klammern können beliebige Anweisungen, mit Semikola oder neuen Zeilen getrennt, stehen.

    Sollte Ihnen manches aus "C" bekannt vorkommen, dann ist dies kein Zufall und die Bedeutungen stimmen überein.


  9. Reguläre Ausdrücke
  10. awk verfügt über folgende Metazeichen bei regulären Ausdrücken:
    	\   ^   $   .   [ ]   |   ( )   *   +   ?
    

    Reguläre Ausdrücke setzen sich aus folgenden Teilausdrücken zusammen:

    • einfaches Zeichen (kein Metazeichen), steht für sich selbst.
    • Das Metazeichen \ schaltet die Bedeutung des folgenden Metazeichens aus.
    • Escape-Sequenzen:
      \b Backspace
      \f Formfeed
      \n Newline
      \r Return
      \t Tabulator
      \ooo Zeichen, das dem Oktalwert ooo entspricht
    • ^ Stringanfang
    • $ Stringende
    • .  beliebiges einfaches Zeichen
    • Zeichenklassen, z.B. [abc] deckt eines der Zeichen a, b oder c ab
    • Zeichenklassen mit Bereichen, z.B. [a-z3-7]
    • Komplettklassen, [^...] deckt alle Zeichen ab, die nicht in ... enthalten sind

    Reguläre Ausdrücke können mit folgenden Operatoren zusammengesetzt werden:

    • Alternation, A|B deckt A oder B ab
    • Konkatenation, AB deckt A unmittelbar gefolgt von B ab
    • null-oder-beliebig-viele, A* deckt kein oder mehr As ab
    • ein-oder-beliebig-viele, A+ deckt ein oder mehr As ab
    • null-oder-eins, A? deckt entweder kein oder genau ein A ab
    • runde Klammern, (A) deckt A ab


    Prioritäten der Operatoren in absteigender Folge:
    ( )
    * + ?
    Konkatenation
    |

  11. Konstanten
  12. Zwei Arten von Konstanten können auftreten:

    • String-Konstanten
      Eine Zeichenkette in Gänsefüßchen eingeschlossen. Im Gegensatz zur Shell findet keine Interpretation statt. So können auch die üblichen Escape-Sequenzen benutzt werden.
    • numerische Konstanten
      Hierunter versteht man in diesem Zusammenhang alle ganzen Zahlen und Gleitkommazahlen wie 3.14 oder 1.6021892e-19. Intern werden alle Zahlen als Gleitkommazahlen gespeichert. Die Genauigkeit ist natürlich maschinenabhängig.

  13. Variablen
  14. Variablen können sowohl Strings, als auch numerische Werte beinhalten. Es muß ihnen kein expliziter Datentyp zugeordnet werden. Während eines Programmablaufs kann dieselbe Variable sowohl Strings, als auch numerische Werte speichern. Der Typ einer Variablen wird immer aus dem Kontext bestimmt. Hierbei werden ggf. Umwandlungen gemäß OFMT vorgenommen. Jede Variable wird mit einem Nullstring bzw. mit Null initialisiert.

    In Ausdrücken können 3 Arten von Variablen verwendet werden:

    • vom Benutzer gewählte Variablen
    • Feld-Variablen
    • built-in Variablen


    vom Benutzer gewählte Variablen:

    Variablen können aus Buchstaben, Ziffern und Unterstrich bestehen.
    Das erste Zeichen muß ein Buchstabe oder der Unterstrich sein!

    Feld-Variablen:

    Feld-Variablen setzen sich aus $ und der Feldnummer zusammen:

    $0
    aktuelle Eingabezeile (Rekord) wird hier abgelegt. $0 ist oft voreingestelltes Argument bei Funkionen, beispielsweise bei print.
    $1...$NF
    der aktuelle Record wird gemäß FS (Feldtrennzeichen) in Felder zerlegt und diese k&oum;nnen mit ihrer Position angesprochen werden (NF - Anzahl der Felder des Satzes).

    Feld-Variablen können genau so wie andere Variablen behandelt werden, insbesondere können ihnen auch neue Werte zugewiesen werden. Diese Zuweisungen beeinflussen $0 und NF!

    Feld-Variablen können auch unter Verwendung von Ausdrücken angegeben werden: $(NF-1) ist das vorletzte Feld der Eingabezeile.

    built-in Variablen:

    Built-in Variablen sind Variablen die awk zur Verfügung stellt und sie mit Werten belegt. Sie geben Auskunft über den momentanen Programmzustand.

    Je nach ihrer Bedeutung werden die Variablen je Eingabezeile gesetzt, durch Aufruf einer Funktion oder am Programm-Anfang.

    ARGC
    Anzahl der Argumente der Kommadozeile (argument count).
    ARGV
    Vektor mit den Argumenten der Kommadozeile (argument vector).
    FILENAME
    Name der momentanen Eingabedatei. Wird bei einer neuen Eingabedatei neu gesetzt.
    FNR
    Anzahl der gelesenen Rekords in der aktuellen Eingabedatei (file number of records).
    FS
    Trennzeichen der Eingabefelder (field seperator). Die Voreinstellung dieser Variable ist ein Leerzeichen.
    NF
    Anzahl der Felder des aktuellen Rekords (number of fields).
    NR
    Anzahl der bislang gelesenen Rekords (number of records). Dieser Zähler zählt über Dateigrenzen hinweg.
    OFMT
    Ausgabe-Format für Zahlen (output format). Voreinstellung ist "%.6g".
    OFS
    Trennzeichen der Ausgabefelder (output field seperator), Voreinstellung ist ein Leerzeichen.
    ORS
    Trennzeichen der Ausgaberekords (output record seperator). Voreinstellung ist "\n".
    RLENGTH
    Länge des Strings, der durch die Funktion match ermittelt wurde.
    RS
    Trennzeichen der Eingaberekords (record seperator). Voreinstellung ist "\n".
    RSTART
    Anfang des Strings, der durch die Funktion match ermittelt wurde.
    SUBSEP
    Trennzeichen der Indizes bei mehrdimensionalen Vektoren (subscript seperator). Voreinstellung ist "\034".

  15. Konkatenation
  16. Für die Konkatenation von Strings gibt es kein Symbol. Die zu konkatenierenden Strings werden einfach hintereinadergehängt. Im Beispiel bekommt gamma den Wert
    	"Gammas Wert ist gleich 17.4"
    
    zugewiesen.
    	alpha = "Gammas Wert"
    	beta = 17.4
    	gamma = alpha " ist gleich " beta
    

  17. Vektoren
  18. awk verfügt über ein- und mehrdimensionale Vektoren. Diese weisen zwei Besonderheiten auf:

    • Die Größe eines Vektors muß nicht explizit angegeben werden. Neue Elemente werden einfach eingefügt. Elemente werden durch ihren Index bestimmt. Existiert ein Index noch nicht, so wird dieser mit entsprechendem Wert in den Vektor eingetragen.
    • Neben den normalen zahlenindizierten Vektoren gibt es assoziative Vektoren, d.h. solche, die über Strings indiziert werden.

    Ein Vektorelement wird durch vektor [index] angesprochen oder initialisiert.

    Beispiel: Zählen von Worten
    	{ for(i=1 ; i<=NF ; i++)
    		feld[i]=feld[i]+1 }
    

    Mehrdimensionale Vektoren verhalten sich wie eindimensionale Vektoren. Intern werden si zu solchen mit Hilfe von SUBSEP umgeformt. Die Indizes werden durch Kommata voneinander getrennt. Im Zusammenhang mit Operatoren sollten die Tupel mit runden Klammern eingeschlossen werden, z.B.:

    	if ((i,j,k) in vektor)
    

  19. Funktionen
  20. In awk können, wie in anderen Programmiersprachen auch, Funktionen definiert werden. Die Definitionen werden üblicherweise am Ende des Programms notiert. Deklarationen sind nicht nötig. Eine Funktionsdefinition genügt der Form

    function name(parameter) { anweisungen }

    Der name muß eindeutig gewählt werden. Mit der return-Anweisung können Funktionen typenlose Rückgabewerte liefern.

    Die Variablenübergabe findet nach dem call-by-value Prinzip statt. Die von Vektoren hingegen nach dem call-by-reference.

    Die Funktionsargumente sind nur im Funktionsrumpf gültig. Neue Variablen, die im Rumpf definiert werden, sind global gültig. Mit einem Trick kann man lokale Variablen erzeugen: Werden beim Funktionsaufruf weniger Argumente angegeben, als bei der Definition, werden die restlichen Argumente mit dem Nullstring initialisiert.



    built-in Funktionen (Arithmetik):

    awk verfügt über folgende arithmetische built-in Funktionen:

    atan2(y,x) Arcustangens von x/y im Intervall [-p,p]
    cos(x) Cosinus von x (x im Bogenmaß)
    exp(x) Exponentialfunktion
    int(x) ganzzahliger Anteil von x
    log(x) natürlicher Logarithmus von x
    rand() Zufallszahl im Intervall [0,1]
    sin(x) Sinus von x (x im Bogenmaß)
    sqrt(x) Quadratwurzel von x
    srand(x) initialisiert den Zufallsgenerator (x ist Startwert)


    built-in Funktionen (String):

    awk verfügt über folgende stringbezogene built-in Funktionen:

    gsub(r,s) ersetzt alle in $0 den String r durch den String s. Rückgabewerte ist die Anzahl der Ersetzungen.
    gsub(r,s,t) ersetzt überall im String t den String r durch den String s. Rückgabewert ist die Anzahl der Ersetzungen.
    index(s,t) sucht das erste Vorkommen des Strings t im String s. Rückgabewert ist die Anfangsposition von t in s, oder 0, wenn String nicht enthalten ist.
    length(s) bestimmt die Länge des Strings s und liefert diesen zurück.
    match(s,r) Überprüft, ob String r ein Teilstring in s abdeckt. Wenn ja, wird die Anfangsposition des Teilstrings zurückgeliefert, ansonsten 0.
    split(s,v) zerlege s entsprechend FS und speichere die Felder im Vektor v. Rückgabewert ist die Anzahl der Felder.
    split(s,v,tr) zerlege s entsprechend tr und speichere die Felder in Vektor v. Rückgabewert ist die Anzahl der Felder.
    sprintf(f,a1,a2,...) formatiert seine Argumente wie printf, allerdings ohne Ausgabe. Rückgabewert ist dann der formatierte String.
    sub(r,s) ersetze in $0 den linken Teil-String r duch s. Rückgabewert ist die Anzahl der Ersetzungen, also 1 oder 0.
    sub(r,s,t) ersetzt in t den linken Teil-String r durch s. Rückgabewert ist die Anzahl der Ersetzungen, also 1 oder 0.
    substr(s,p) liefert ab Position p den Rest von s.
    substr(s,p,n) liefert ab Position p den Teil-String mit n Zeichen aus s.
     
    In der Tabelle steht r für einen regulären Ausdruck, s und t für Strings, n und p für ganze Zahlen.

  21. Operatoren
  22. Operatoren in awk mit abnehmender Priorität:

    () Gruppierungs-Operator -->
    $ Feldoperator -->
    ++ -- Postfix-Operator -->
    ++ -- Präfix-Operator -->
    ^ Potenzierungs-Operator <--
    ! logische Negation -->
    + - Vorzeichen-Operationen -->
    * / % Multiplikation, Division, Modulo -->
    + - Addition, Subtraktion -->
      Konkatenation -->
    < <= == != >= > relationale Operatoren -->
    ~ !~ Beinhaltungs-Operator -->
    in Vektor-Mitglieds-Operator -->
    && logisches UND -->
    || logisches ODER -->
    ? : Bedingungs-Operator -->
    = += -= *= /= %= ^= Zuweisung <--

    Ein <-- steht für "die Auswertung beginnt rechts", analog -->.


  23. Ausgabe-Anweisungen
  24. Für die Ausgabe stehen zwei Funktionen zur Verfügung: print und printf. printf ist wie in C zu benutzen. Bei der Aufzählung werden die Variablen $0, OFS, ORS benutzt.

    print

    gibt $0 auf stdout auf (entspricht print $0)

    print ausdruck1, ausdruck2, ...

    gibt die Ausdrücke in der angegebenen Reihenfolge durch OFS getrennt auf stdout aus. Abschließend wird ORS ausgegeben.

    Hinweis: print ausdruck1 ausdruck2 (ohne Komma!) bewirkt Ausgabe ohne Trennzeichen!

    printf(format, ausdruck1, ausdruck2,...)

    Die Ausdrücke werden gemäß dem Formatstring ausgegeben.

    Mit den Symbolen >Dateiname, >> Dateiname und | Kommando am Ende der Ausgabe-Funktion, kann die Ausgabe umgeleitet werden.

    Dateien, die Sie öffnen, sollten Sie auch wieder schließen. Zum einen dürfen Sie meistens nur eine sehr endliche Zahl von Dateien gleichzeitig geöffnet haben , zum anderen kann es sonst Schwierigkeiten beim Puffern von Dateien geben, wenn mit denen anderweitig gearbeitet wird. Auch Pipes müssen wieder geschlossen werden!

    Sie erreichen dies mit:

    close(dateiname)
    close(kommando)

    Hierbei muß der komplette Name des Aufrufs wieder angegeben werden.


  25. Eingabe mit getline
  26. Mit dieser Funktion kann explizit der nächste Eingabe-Rekord gelesen werden. Das Programm führt dann mit der gegenwärtigen Abarbeitung fort und wird nicht neu gestartet. getline kann drei Rückgabewerte annehmen: 1, wenn der Rekord gelesen werden konnte; 0, wenn das Dateiende erreicht ist und -1, wenn beim Lesen ein Fehler auftrat.

    getline kann auf folgende Weisen eingesetzt werden:

    Ausdruck setzt
    getline $0, NF, NR, FNR
    getline variable variable, NR, FNR
    getline <dateiname $0, NF
    getline variable < dateiname variable
    kommando | getline $0, NF
    kommando | getline variable variable


  27. Standard-Files
  28. In einigen awk-Implementierungen stehen die Standard-Dateiverbindungen zur Verfügung. Sie können dann über /dev/stdin, /dev/stdout, /dev/stderr und /dev/fd/n angesprochen werden. Der letzte Name bezeichnet einen Filedeskriptor.


  29. Formatbefehle für printf und sprintf
  30. Das erste Argument der Befehle printf und sprintf ist ein Formatstring, der die Formatierung der nachfolgenden Argumente bestimmt. C-Programmierer kennen diese Methode schon. Die Anzahl der Argumente muß mit der im Formatstring korrespondieren. Die Zuordnung findet durch die Reihenfolge statt. Der Formatstring ist ein normaler String mit beliebigem Inhalt und zusätzlichen Befehlen.

    Ein Befehl setzt sich aus mehreren Teilen zusammen:

    %[-][feldgröße][.genauigkeit]formatzeichen

    Hierbei sind die [ ] optionale Symbole. Das % leitet eine Formatbefehl ein. Wird das - angegeben, so erfolgt der Eintrag linksbündig. Die Feldgröße gibt die Größe des Feldes an. Ist das Argument an dieser Stelle größer, wird die Feldgröße ignoriert. Die Genauigkeit gibt die Stellen an, die nach dem Komma bei rationalen Zahlen gedruckt werden sollen; bei Strings die Anzahl der maximal zu druckenden Stellen. Die Formatzeichen entnehmen Sie der folgenden Tabelle:

    c Ein ASCII-Zeichen. Ist das entsprechende Argument eine Zahl, so wird diese als Kode im Zeichensatz interpretiert und ausgegeben.
    d Integerzahl
    i Eine vorzeichenbehaftete ganze Zahl.
    e Eine Gleitkommazahl der Form: [-]d.ddddddE[+-]dd
    f Eine Gleitkommazahl der Form: [-]ddd.dddddd
    g das Argument wird entweder wie e oder f umgewandelt. Je nachdem, welches Ergebnis kürzer ist. Nicht signifikante Nullen werden dabei unterdrückt.
    o Eine vorzeichenlose Oktalzahl.
    s Ein String.
    x Eine vorzeichenlose Hexadezimalzahl mit Kleinbuchstaben.
    X Eine vorzeichenlose Hexadezimalzahl mit Großbuchstaben.
    % Hebt die bedeutung von % auf. Also %% gibt % aus.

  31. Die Funktion system
  32. Die Funktion system(ausdruck) führt das durch ausdruck spezifizierte Kommando in der Shell aus. Der Rückgabewert der Funktion ist der Exit-Status des Kommandos.

  33. Einsatzmöglichkeiten
  34. awk kann auf vielfältige Weise eingesetzt werden. Größere Textmanipulationen, bei denen sich sed als nicht besonders benutzerfreundlich herausstellt, ist ein Bereich. Die Entwicklung eines großen Programmes zum Testen , ein anderer. Oft wird awk aber auch nur als Einzeiler - innerhalb einer Pipe - aufgerufen, um bestimmte Felder zu filtern.

    Der größte Nachteil von awk ist seine Verarbeitungsgeschwindigkeit. Hierbei gehört es nicht gerade zu den Hochleistungssportlern. Deshalb nehmen Sie bei Textmanipulationen, bei denen es möglich ist, lieber sed. Ist dies nicht möglich und ist die Verarbeitungsgeschwindigkeit wichtig, so ü'berlegen Sie sich eine perl-Variante des Programms.


  35. awk-Programmbeispiel
  36. Programm zur Auswertung der Getränke-Datei:

    prog.awk
    BEGIN	{
       getr["Kaffee"]=0.50
       getr["Tee"]=0.40
       getr["Bier"]=2.10
       getr["Wasser"]=1.00
       getr["Saft"]=1.50
    
    a_kaffee=0 a_tee=0 a_bier=0 a_wasser=0 a_saft=0 a_ges=0 }
    /^#/ { if(u_ges>0) { printf("\t===========|==========|===========|") printf("===========\n") printf("\tGesamtsumme:--------------------") printf("--> %8.2f\n",u_ges) u_ges=0 } printf("\n\n\n") printf("Getraenkeverzehr von %s\n",substr($0,2)) printf("------------------------------------") printf("------------------\n") printf("\tGetraenk | Anzahl | E-Preis |") printf(" G-Preis\n") printf("\t-----------|----------|-----------|") printf("-----------\n") }
    /^[^#]/ { art=substr($1,1,length($1)-1) printf("\t%8s |..%4d |",art,$2) printf(" %7.2f | %7.2f\n",getr[art],getr[art]*$2) u_ges+=(getr[art]*$2) }
    END { if(u_ges>0) { printf("\t===========|==========|===========|") printf("===========\n") printf("\tGesamtsumme:--------------------") printf("--> %8.2f\n",u_ges) u_ges=0 } printf("\n\n\n") }
    Aufbau der Getränke-Datei:

    prog.dat
    	#Klaus
    	Bier: 2
    	Kaffee: 18
    	Saft: 9
    	Tee: 25
    	Wasser: 27
    	#Elke
    	Bier: 1
    	Kaffee: 5
    	Saft: 19
    	Tee: 25
    	Wasser: 37
    	#Hans
    	Bier: 3
    	Kaffee: 1
    	Saft: 29
    	Tee: 35
    	Wasser: 17
    
    Aufrufendes Programm:

    rechnung
    	awk -f prog.awk prog.dat>liste
    
    Ergebnis:

    liste
    Getraenkeverzehr von Klaus
    ------------------------------------------------------
    	Getraenk   |  Anzahl  |  E-Preis  |  G-Preis
    	-----------|----------|-----------|-----------
    	    Bier   |     2    |     2.10  |     4.20
    	  Kaffee   |    18    |     0.50  |     9.00
    	    Saft   |     9    |     1.50  |    13.50
    	     Tee   |    25    |     0.40  |    10.00
    	  Wasser   |    27    |     1.00  |    27.00
    	===========|==========|===========|===========
    	Gesamtsumme:---------------------->    63.70
    
    Getraenkeverzehr von Elke
    ------------------------------------------------------
    	Getraenk   |  Anzahl  |  E-Preis  |  G-Preis
    	-----------|----------|-----------|-----------
    	    Bier   |     1    |     2.10  |     2.10
    	  Kaffee   |     5    |     0.50  |     2.50
    	    Saft   |    19    |     1.50  |    28.50
    	     Tee   |    25    |     0.40  |    10.00
    	  Wasser   |    37    |     1.00  |    37.00
    	===========|==========|===========|===========
    	Gesamtsumme:---------------------->    80.10
    
    Getraenkeverzehr von Hans
    ------------------------------------------------------ Getraenk | Anzahl | E-Preis | G-Preis -----------|----------|-----------|----------- Bier | 3 | 2.10 | 6.30 Kaffee | 1 | 0.50 | 0.50 Saft | 29 | 1.50 | 43.50 Tee | 35 | 0.40 | 14.00 Wasser | 17 | 1.00 | 17.00 ===========|==========|===========|=========== Gesamtsumme:----------------------> 81.30

    Vorstehendes Beispiel wertet eine Getränkedatei aus, in der die innerhalb eines bestimmten Zeitraumes verzehrten Getränke verschiedener Systembenutzer aufgelistet sind.

    Zunächst werden im Abschnitt BEGIN alle Variablen und ein assotiatives Feld initialisiert. Der Index für den Zugriff auf dieses Feld ist die in der Getränkedatei benutzte Getränkebezeichnung.

    Es werden durch das Suchkriterium /^#/ alle Zeilen selektiert, die mit dem Zeichen # beginnen. Das sind die Zeilen, die den Benutzer ausweisen, für den die nachfolgenden Daten gelten. Durch das Suchkriterium /^[^#]/ werden dagegen alle Zeilen selektiert, die nicht mit dem Zeichen # beginnen. Das Entfernen des Doppelpunktes im Getränkenamen ist notwendig, da ansonsten der Index nicht zum assoziativen Feld passen würde.

    Der Abschnitt END sorgt dafür, daß auch für den letzten in der Datei eingetragenen Benutzer die Summe ausgegeben wird.


  37. Literaturhinweise
  38. Helmut Herold: AWK und SED, Addison Wesley, 1991
    Kernighan, Pike: Der UNIX-Werkzeugkasten, Hanser, 1986
    Aho, Kernighan, Weinberger: The AWK Programming Language, Addison Wesley
    Close, Robbins, Rubin, Stallman: The GAWK Manual, GNU, 1992


 Universität   Service   URZ-S   Unix     Impressum  Autor:  Matthias Mahrholz    02-11-09