gawk/Datenfelder und Variablen

Aus Foxwiki


Datenfelder und Variablen

Wichtige eingebaute Variablen

  • Awk arbeitet unter der Annahme, dass die Eingabe strukturiert ist.
  • Im einfachsten Fall interpretiert awk jede Eingabezeile als Datensatz und jedes enthaltene Wort als Feld. Ein Wort ist dabei jede von Feldseparatoren begrenzte Zeichenfolge.
  • In der Voreinstellung trennen Leerzeichen und Tabulatoren Wörter; durch Belegung der builtin-Variablen FS lassen sich beliebige Separatoren definieren.
  • Über den Feldoperator $ gestattet Awk den Zugriff auf die Felder der zuletzt eingelesenen Eingabezeile.
  • Im Unterschied zur Programmiersprache C beginnt die Nummerierung der Felder bei 1 und - im Gegensatz zu den Positionsparametern der Shell - endet sie nicht bei 9 (implementierungsabhängig werden 100 Felder garantiert; gawk auf x86-Architektur kann vermutlich 232 Felder indizieren).

Um z. B. das 1. und 11. Feld einer Eingabezeile auszugeben, hilft Folgendes:

$ echo "0 1 2 3 4 5 6 7 8 9 10 11" | awk '{print $1,$11;}'
0 10

Der Feldoperator $0 steht für die gesamte Zeile; die Anzahl der Felder der aktuell bearbeiteten Zeile ist in der Variablen NF gespeichert.

$ echo "0 1 2 3 4 5 6 7 8 9 10 11" | awk '{print NF,$0;}'
12 0 1 2 3 4 5 6 7 8 9 10 11
  • Die aktuelle Zeilennummer hält Awk in der Variablen NR.

Um die Zeilen einer Datei zu nummerieren, könnte somit folgender Aufruf dienen:

$ awk '{print NR,$0;}' <zu_nummerierende_Datei>
  • Bei aufmerksamer Betrachtung des einführenden Beispiels »head.awk« ist Ihnen vermutlich aufgefallen, dass wir dort FNR anstatt NR zur Nummerierung verwendeten.
  • Der Unterschied ist, dass Letzteres (NR) fortlaufend die Anzahl der Durchläufe der Hauptschleife zählt, während FNR im Falle mehrerer Eingabedateien die Zählung für jede Datei von vorn beginnt.

Beispiel

»wc -l« mit Mitteln von Awk, wobei außerdem die Variable FILENAME verwendet wird, die den Namen der aktuell bearbeiteten Datei enthält :

#!/usr/bin/awk -f

BEGIN { zeile=0; }
{
if ( zeile > FNR ) {
print zeile,FILENAME;
zeile=0;
}
else zeile++;
}
END {
print FNR, FILENAME
if ( FNR != NR ) { print NR, "insgesamt"; }
}

Als Testfall wenden wir das kleine Programm auf sich selbst an und vergleichen die Ausgabe mit der von »wc -l«:

$ ./wc-l.awk /etc/fstab /etc/passwd
17 /etc/passwd
46 /etc/passwd
63 insgesamt
$ wc -l /etc/fstab /etc/passwd
17 /etc/fstab
46 /etc/passwd
63 insgesamt
  • Abgesehen von der Formatierung (wir später noch behoben) verhält sich unser Programm exakt wie das Vorbild.
  • Eher unüblich ist die Manipulation der Variablen RS, die den Zeilenseparator spezifiziert.
  • Sinnvoll ist es für Datensätze, die über mehrere Zeilen verteilt stehen und ein anderes Zeichen (bspw.
  • eine Leerzeile) eine eindeutige Strukturierung erlaubt.
  • Das die Ausgabe von Awk betreffende Pedand zu RS ist der Output Record Selector (ORS).
  • In der Voreinstellung dient der Zeilenumbruch zur Separierung der Ausgaben; durch Neubelegung von ORS kann dies geändert werden.
  • Nachfolgender Kommandoaufruf ersetzt die Unix-Dateiendung (Newline) durch das Windows-Äquivalent (Carriage Return, Newline):
$ awk 'BEGIN {ORS="\r\n";}{print $0;}' <Datei>
  • Natürlich hätte es auch »recode« getan...
  • Neben ORS zum Ändern des Zeilenseparators existiert mit OFS eine Variable, die das Trennzeichen für einzelne Datenfelder (Voreinstellung: Leerzeichen) festlegt.

Weitere eingebaute Variablen

  • Die weiteren von Awk verwendeten internen Variablen sollen an dieser Stelle nur kurz benannt werden.
  • Einigen Vertretern werden wir später erneut begegnen.
CONVFMT Steuert die Konvertierung von Zahlen in Zeichenketten.
  • Die Voreinstellung »%.6g« bewirkt, dass Gleitkommazahlen mit einer Genauigkeit von bis zu 6 Ziffern konvertiert werden.
  • Die zulässigen Werte sind genau jene, die auch »printf« zur Zahlenausgabe verwendet:
$ awk 'BEGIN { print "Pi = " 3.1415926532; }'
Pi = 3.14159
$ awk 'BEGIN { CONVFMT="%.10g"; print "Pi = " 3.1415926532; }'
Pi = 3.141592653
ENVIRON Die Feldvariable ENVIRON enthält alle Umgebungsvariablen.
  • Der Index ist hierbei der Name der Umgebungsvariablen:
$ awk 'BEGIN { print ENVIRON["HOME"]; }'
/home/user
IGNORECASE Steuert die Unterscheidung von Klein- und Großschreibung beim Mustervergleich.
  • Steht die Variable auf »0« sind bspw. "ab" und "Ab" unterschiedliche Zeichenketten.
  • Bei jedem Wert ungleich »0«, spielt Klein- und Großschreibung keine Rolle.
OFMT OFMT steuert das Ausgabeformat von Zahlen durch das Kommando print. Die Verwendung erfolgt analog zu CONVFMT
RLENGTH Länge der übereinstimmenden Teilzeichenkette der Zeichenkettenfunktion match()
RSTART Index des Beginns der übereinstimmenden Teilzeichenkette mit der Zeichenkettenfunktion match()
SUBSEP Das Zeichen, das in Feldvariablen die einzelnen Elemente trennt (\034).

Eigene Variablen

Datentypen

  • Awk unterscheidet einzig (Gleitkomma-)Zahlen und Zeichenketten.
  • Von welchem Typ eine Variable ist, hängt vom aktuellen Kontext ab.
  • Findet eine numerische Berechnung statt, werden die beteiligten Variablen als Zahlen interpretiert und bei Zeichenkettenoperationen eben als Zeichenketten.
  • Notfalls lässt sich ein konkreter Kontext erzwingen, indem bspw.
  • der Wert '0' zu einer Variable addiert oder die leere Zeichenkette "" an eine solche angehangen wird.

Internen Konvertierungen

  • Für den Awk-Programmierer von Interesse sind die internen Konvertierungen, die beim Vergleich von Variablen stattfinden.
  • Zwei numerische Variablen werden als Zahlen verglichen, genauso wie zwei Zeichenkettenvariablen als Zeichenketten verglichen werden.
  • Ist eine Variable eine Zahl und die andere eine numerische Zeichenkette, so wird die Zeichenkette in eine Zahl konvertiert.
  • Handelt es sich um keine numerische Zeichenkette, wird die Variable mit der Zahl in eine Zeichenkette gewandelt und nachfolgend ein Vergleich der Zeichenketten vorgenommen.

Variablennamen

  • Variablennamen in Awk dürfen aus Buchstaben, Ziffern und dem Unterstrich bestehen, wobei zum Beginn keine Ziffer stehen darf.
  • Klein- und Großschreibung werden unterschieden, sodass bspw.
  • Variable, variable, und VARIABLE unterschiedliche Bezeichner sind.
  • Eine Variable wird definiert, indem sie benannt und ihr ein Wert zugewiesen wird.
  • Die in anderen Programmiersprachen üblichen Typbezeichner kennt Awk nicht.
  • Eine Variable kann auch nur deklariert werden, awk initialisiert sie dann selbsttätig als leeren Zeichenkette.