gawk/Eingebaute Funktionen

Aus Foxwiki


Eingebaute Funktionen

  • Der bevorzugte Einsatzbereich von Awk ist die automatische Generierung von Reports und Statistiken.
  • So existieren zahlreiche eingebaute Funktionen, die Awk zur Auswertung von Daten jeglicher Art prädestinieren.
  • Eine Funktion ist gekennzeichnet durch einen Namen und der Liste der Argumente, die dem Namen, eingeschlossen in runde Klammern, folgen.
  • Es ist bei einigen Funktionen zulässig, weniger Argumente anzugeben, als die Funktion eigentlich bedingt; welche voreingestellten Werte dann Awk einsetzt, unterscheidet sich von Funktion zu Funktion.
  • Stets ein Syntaxfehler hingegen ist, mehr Argumente einer Funktion mitzugeben, als bei ihrer Definition vereinbart wurden.
  • Finden Ausdrücke als Argumente Verwendung, so werden diese vor der Übergabe an die Funktion ausgewertet, d.h.
  • bspw Funktion(i++); liefert (zumeist) ein anderes Ergebnis als Funktion(i); i++;.
  • Allerdings ist die Reihenfolge der Auswertung der Argumente unspezifiziert; eine Funktion wie atan2(x++, x-1); kann in unterschiedlichen Implementierungen zur unterschiedlichen Ergebnissen führen.

Mathematische Funktionen

Zur numerischen Berechnung stellt Awk folgende Funktionen zur Verfügung:

Liefert den Arcus-Tangens (in rad) von x/y
cos(x) Liefert den Consinus von x
exp(x) Berechnet ex
int(x) Ganzzahliger Wert von x, wobei »in Richtung 0« gerundet wird
log(x) Liefert den natürlichen Logarithmus von x
rand() Liefert eine Zufallszahl im Bereich von [0,1]
sin(x) Liefert den Sinus von x
sqrt(x) Liefert die Quadratwurzel von x
srand([x]) Setzt den Startwert für die Zufallszahlen-Generierung [mittels rand()].
  • Geliefert wird der »alte« Startwert
  • Die Funktion zur Erzeugung von Zufallszahl liefert nicht wirklich zufällige Zahlen, sondern eine Folge relativ gleichverteilter Zahlen im Intervall [0,1].
  • Mit jedem Start eines Awk-Programms wird somit stets dieselbe Folge von Zufallszahlen generiert.
  • Genügt dieser »Zufall« nicht aus, muss mit srand() ein neuer Bezugspunkt für rand() gesetzt werden. srand() ohne Argument erzeugt diesen Startwert aus aktuellem Datum und Uhrzeit, womit rand() tatsächlich den Eindruck zufälliger Werte erweckt.
  • Einige Anwendungsbeispiele sollen die Verwendung der Funktionen demonstrieren:
# Berechnung von π
$ awk 'BEGIN { printf("π=%.50f\n", 4*atan2(1,1)); }'
π=3.14159265358979311599796346854418516159057617187500
# Ganzzahliger Anteil eines Wertes
$ awk 'BEGIN { print int(-7), int(-7.5), int (7), int(7.5)}'
-7 -7 7 7
# Der natürliche Logarithmus von e1
$ awk 'BEGIN { print log(exp(1))}'
1

Anmerkung

  • Das Beispiel der Berechnung von π zeigt die Genauigkeitsschranke der verwendeten Awk-Implementierung; ab der 48. Nachkommastelle ist Schluss.
  • Allerdings genügt die interne Darstellung, um bei Umkehrrechnungen auf den Ausgangswert zu kommen (log(exp(1))).

Zeichenkettenfunktionen

  • Die nachfolgend diskutierten Funktionen durchsuchen oder manipulieren Zeichenketten.
gsub(Regular expression,Ersatz,[String]) Jedes Vorkommen des Regulären Ausdrucks Regular expression in String wird durch Ersatz ersetzt.
  • Wird String nicht angegeben, wird $0 bearbeitet.
  • Rückgabewert ist die Anzahl der Ersetzungen.
index(Suchstring,Muster) Liefert die Position, an der Muster in Suchstring erstmals vorkommt oder 0
length([String]) Liefert die Länge von String; fehlt String, wird die länge von $0 zurückgegeben
match(String,Regular expression) Liefert die Position des ersten Auftretens des Regulären Ausdrucks Regular expression in String; setzt RSTART und RLENGTH
split(String,Feld,[Seperator]) Zerlegt String in einzelne Elemente und legt diese in Feld ab.
  • Als Trennzeichen dient Seperator oder FS, falls dieser nicht angegeben wurde.
  • Rückgabewert ist die Anzahl der Elemente.
sprintf("Format",Ausdruck) Anwendung wie printf, anstatt einer Ausgabe gibt die Funktion die resultierende Zeichenkette zurück
sub(Regular expression,Ersatz,[String]) Arbeitsweise wie gsub, es wird aber nur das erste Muster ersetzt
substr(string,p,[l]) Gibt eine Teilzeichenkette von string der Länge l, beginnend an Position p zurück
tolower(string) Wandelt Groß- in Kleinbuchstaben um, Rückgabewert ist die neue Zeichenkette
toupper(string) Wandelt Klein- in Großbuchstaben um, Rückgabewert ist die neue Zeichenkette

Ermitteln der längsten Zeile einer Datei

$ expand default.htm | awk '{x = (x < length()) ? length():x;} END {print x}'
566

In welcher Zeile und welcher Position erscheint ein Muster

$ awk '/Partitionstabelle/ {print "Zeile:", NR, "Spalte", index($0,"Partitionstabelle")}' Linuxfibel/installbefore.htm 
Zeile: 804 Spalte 14
Zeile: 818 Spalte 81
Zeile: 837 Spalte 57
Zeile: 838 Spalte 41
Zeile: 843 Spalte 41
Zeile: 972 Spalte 12

Sonstige Funktionen

close(Datei) Schließt eine zuvor zum Lesen oder Schreiben geöffnete Datei oder die Pipe, die als Eingabe oder Ausgabe eines Kommandos diente (dann muss anstatt eines Dateinamens der Kommandoaufruf angegeben werden)
fflush(Datei) Leert unverzüglich den Puffer einer »gepufferten« Ausgabe.
  • D.h.
  • veränderte Daten einer Datei werden sofort zurückgeschrieben oder die in eine Pipe geleitete Ausgabe eines Kommandos wird sofort aus dieser entnommen.
  • Bei fehlendem Argument entleert Gawk die Standardausgabe; bei Angabe der leeren Zeichenkette ("") werden die Puffer sämtlicher offener Ausgabedateien und Pips entleert.
system(Kommando) Gestattet die Ausführung von beliebigen Kommandos.
  • Nach Ende eines solchen wird im Awk-Programm fortgefahren.
  • system liefert den Status des letzten gestarteten Kommandos zurück.
systime() Liefert die Systemzeit in Sekunden (seit 1.1.1970)
strftime([Format [,Zeitstempel]]) Liefert eine Datumszeichenkette.
  • Ohne Zeitstempel wird die aktuelle Systemzeit verwendet, das Format entspricht dem der gleichnamigen C-Funktion.
  • Beispiele zur Anwendung von close() finden sich im Text genügend.

Hier soll eine unnütze Anwendung von systime() den Abschnitt beschließen.

$ awk 'BEGIN { start = systime();
> for (i = 1; i < 10000000; i++));
> end = systime();
> print "Gesamtzeit betrug", end - start, "Sekunden.";
}'
Gesamtzeit betrug 6 Sekunden.