awk/Ausgabe anzeigen: Unterschied zwischen den Versionen

Aus Mikiwiki
< awk
Zur Navigation springen Zur Suche springen
Zeile 108: Zeile 108:


{| class=wikitable width=100%
{| class=wikitable width=100%
! width=10% | !! Bedeutung || Beispiel
! width=5% | !! Bedeutung || Beispiel
|-
|-
| %c
| <tt>%c</tt>
| Ausgabe einer Zahl als ASCII-Zeichen.
| Ausgabe einer Zahl als ASCII-Zeichen.
| Ausgabe des Buchstabens "A".
| Ausgabe des Buchstabens "A".
Zeile 120: Zeile 120:
|  
|  
|-
|-
| %e<br>%E
| <tt>%e<br>%E</tt>
| Ausgabe einer Zahl in wissenschaftlicher (exponentialer) Schreibweise. "%E" verwendet "E" anstatt "e" in der Ausgabe.
| Ausgabe einer Zahl in wissenschaftlicher (exponentialer) Schreibweise. "%E" verwendet "E" anstatt "e" in der Ausgabe.
| Ausgabe von "1.950e+03" mit vier siginifikanten Zeichen, davon drei nach dem Dezimalpunkt. "4.3" bezeichnet zwei "modifiers".
| Ausgabe von "1.950e+03" mit vier siginifikanten Zeichen, davon drei nach dem Dezimalpunkt. "4.3" bezeichnet zwei "modifiers".
Zeile 126: Zeile 126:
  printf "%4.3e\n", 1950
  printf "%4.3e\n", 1950
|-
|-
| %f
| <tt>%f</tt>
| Ausgabe einer Zahl in Fliesskommaschreibweise.
| Ausgabe einer Zahl in Fliesskommaschreibweise.
| Ausgabe von "1950.000" mit gesamt vier signifikanten Zeichen, wovon drei nach dem Komma folgen. "4.3" bezeichnet zwei "modifiers".
| Ausgabe von "1950.000" mit gesamt vier signifikanten Zeichen, wovon drei nach dem Komma folgen. "4.3" bezeichnet zwei "modifiers".
Zeile 132: Zeile 132:
  printf "%4.3f", 1950
  printf "%4.3f", 1950
|-
|-
| %g<br>%G
| <tt>%g<br>%G</tt>
| Ausgabe einer Zahl entweder in wissenschaftlicher Schreibweise oder in Fliesskommaschreibweise, je nach dem welcher weniger Zeichen verwendet. Falls das Ergebnis in wissenschaftlicher Schreibweise geschrieben wird, verwendet "%G" ein grosses "E" anstatt "e".
| Ausgabe einer Zahl entweder in wissenschaftlicher Schreibweise oder in Fliesskommaschreibweise, je nach dem welcher weniger Zeichen verwendet. Falls das Ergebnis in wissenschaftlicher Schreibweise geschrieben wird, verwendet "%G" ein grosses "E" anstatt "e".
|  
|  
|-
|-
| %o
| <tt>%o</tt>
| Ausgabe einer Oktalzahl.
| Ausgabe einer Oktalzahl.
|  
|  
|-
|-
| %s
| <tt>%s</tt>
| Ausgabe einer Zeichenkette.
| Ausgabe einer Zeichenkette.
|  
|  
|-
|-
| %u
| <tt>%u</tt>
| Ausgabe einer Dezimalzahl. Die Verwendung ist selten, da in awk alle Zahlen als Fliesskommazahlen angesehen werden. Der Bezeichner existiert aus Kompatibilitätsgründen zu ISO C.
| Ausgabe einer Dezimalzahl. Die Verwendung ist selten, da in awk alle Zahlen als Fliesskommazahlen angesehen werden. Der Bezeichner existiert aus Kompatibilitätsgründen zu ISO C.
|  
|  
|-
|-
| %x<br>%X
| <tt>%x<br>%X</tt>
| Ausgabe einer Hexadezimalzahl. "%X" verwendet dabei die Grossbuchstaben "A" bis "F" anstatt "a" bis "f".
| Ausgabe einer Hexadezimalzahl. "%X" verwendet dabei die Grossbuchstaben "A" bis "F" anstatt "a" bis "f".
|  
|  
|-
|-
| %%
| <tt>%%</tt>
| Das ist zwar kein Formatbezeichner, gibt jedoch das Zeichen "%" aus.
| Das ist zwar kein Formatbezeichner, gibt jedoch das Zeichen "%" aus.
|  
|  

Version vom 20. Januar 2009, 17:31 Uhr

Eine der häufigsten awk-Aktionen ist es, einen Teil der oder die ganze Eingabe anzuzeigen oder auszugeben. Zu diesem Zweck gibt es unter awk zwei Anweisungen:

  • print zeigt einfache Ausgaben an. Die Anweisung kann alle Werte anzeigen, jedoch (mit zwei Ausnahmen) nicht die Art und Weise der Anzeige beeinflussen, z. B. kann die Anzeige nicht spaltenweise erfolgen.
  • printf wird für ausgefallenere Darstellungen der Ausgabe verwendet.

Die Anweisung "print"

Die Anweisung "print" wird zur Anzeige einer Ausgabe mit einfacher, standardisierter Formatierung verwendet. Dazu werden die anzuzeigenden Zeichenketten oder Zahlen in einer durch Kommas getrennten Liste angegeben. Sie werden dann durch Leerschläge getrennt angezeigt und durch einen Zeilenumbruch abgeschlossen. Die Anweisung lautet wie folgt:

print Element1, Element2, ...

Die ganze Liste der Elemente kann bei Bedarf in Klammern gesetzt werden. Die Klammern sind zwingend nötig, wenn irgendeines der Elemente den relationalen Operator ">" verwendet; andernfalls könnte das Zeichen mit einer Umleitung verwechselt werden.

Die anzeigbaren Elemente können konstante Zeichenketten oder Zahlen, Felder des aktuellen Datensatzes (z. B. "$1"), Variablen oder ein beliebiger awk-Ausdruck sein. Zahlenwerte werden dabei vor der Anzeige in Zeichenketten umgewandelt.

Die einfache Anweisung "print" ohne Elemente ist gleichwertig mit "print $0" - dabei wird der ganze aktuelle Datensatz ausgegeben. Um eine Leerzeile auszugeben, wird "print """ verwendet, wobei die beiden Anführungszeichen die leere Zeichenkette bedeuten. Um ein festes Textstück auszugeben, wird eine Zeichenkettenkonstante verwendet, z. B. "Keine Panik" als ein Element, begrenzt durch Anführungszeichen. Zwischen jeweils zwei Elementen wird immer ein Leerschlag ausgegeben.

Beispiele für "print"-Anweisungen

Jede "print"-Anweisung erzeugt mindestens eine Ausgabezeile. Falls eine Zeichenkette das Zeilenumbruchszeichen ("\n") enthält, können auch mehrere Zeilen erzeugt werden.

Ausgabe einer Zeichenkette, die einen eingebetteten Zeilenumbruch enthält.

$ awk 'BEGIN { print "Zeile 1\nZeile 2" }'
Zeile 1
Zeile 2

Ausgabe der ersten beiden Felder (jeweils getrennt durch einen Leerschlag) jedes Eingabe-Datensatzes der Datei "inventory".

$ awk '{ print $1, $2 }' inventory
Jan 13
Feb 15
...

Ein typischer Fehler im obigen Beispiel ist das Vergessen des Kommas zwischen den beiden auszugebenden Feldern (also "$1 $2" anstatt "$1, $2"). In diesem Falle werden die beiden Felder ohne Leerschlag direkt aneinandergehängt.

$ awk '{ print $1 $2 }' inventory
Jan13
Feb15
...

Ausgabe einer Überschriftszeile sowie der ersten beiden Felder (jeweils getrennt durch einen Leerschlag) jedes Eingabe-Datensatzes der Datei "inventory". Damit die Überschriften mit den Längen der ausgegebenen Felder übereinstimmen, können zusätzliche Leerschläge (hier nur einer: "♦") zwischen den beiden Feldern eingefügt werden.

$ awk 'BEGIN { print "Monat Kisten"
               print "----- ------" }
             { print $1, "  ", $2 }' inventory
Monat Kisten
----- ------
Jan   13
Feb   15

Für schwierigere Formen der Ausgabe wird meist die Anweisung "printf" verwendet.

Ausgabetrenner

Eine "print"-Anweisung beinhaltet immer eine Liste von durch Kommas getrennten Elementen. In der Ausgabe werden die Elemente standardmässig durch Leerschläge voneinander getrennt. Durch Belegung der Variable "OFS" kann der Ausgabefeldtrenner (engl. output field separator) auch auf ein anderes Zeichen gesetzt werden. Standardmässig hat diese Variable als Wert die Zeichenkette "♦", also einen Leerschlag.

Die Ausgabe einer "print"-Anweisung heisst Ausgabedatensatz. Jede "print"-Anweisung gibt einen solchen Ausgabedatensatz aus und schliesst daran einen Ausgabedatensatztrenner (engl. output record separator) an, der durch die Variable "ORS" bestimmt ist. Standardmässig hat diese Variable "\n" als Wert, also einen Zeilenumbruch. Dadurch erzeugt normalerweise jede "print"-Anweisung eine eigene Zeile.

Eine Änderung der Variablen "OFS" und "ORS" wird üblicherweise in der Regel "BEGIN" vorgenommen, damit sie gesetzt sind, bevor irgendeine Verarbeitung der Daten stattfindet. Die beiden Variablen können auch durch Zuweisung auf der Befehlszeile oder durch Verwendung der Option "-v" verändert werden.

Ausgabe des ersten und zweiten Felds jedes Eingabedatensatzes, getrennt durch einen Strichpunkt, wobei nach jedem Zeilenumbruch eine Leerzeile (bzw. ein weiterer Zeilenumbruch) eingefügt wird.

$ awk 'BEGIN { OFS = ";" ; ORS ="\n\n" }
             { print $1, $2 }' bbslist
aardvark;555-5553

alpo-net;555-3412

...

Gleichwertige Befehle für diesen Vorgang sind:

$ awk '{ print $1, $2 }' OFS=";" ORS="\n\n" bbslist
$ awk -v OFS=";" -v ORS="\n\n" '{ print $1, $2 }' bbslist

Steuerung von numerischen Ausgaben mit "print"

Bei der Ausgabe numerischer Werte mit der Anweisung "print" wandelt awk die Zahlen intern in eine Zeichenkette um und gibt diese aus. awk verwendet dafür die Funktion "sprintf", welche eine Formatspezifikation entgegennimmt, welche sagt, wie die Zahlen (oder Zeichenketten) formatiert werden sollen. Dabei können Zahlen auf verschiedene Weise formatiert werden.

Die eingebaute Variable "OFMT" enthält die Standardformatspezifikation, die "print" mit "sprintf" verwendet, wenn eine Zahl zu Ausgabezwecken in eine Zeichenkette umgewandelt wird. Der Standardwert der Variable "OFMT" ist "%.6". Die Art, wie die Anweisung "print" Ausgaben erzeugt, kann durch Neubelegung der Variable "OFMT" verändert werden.

$ awk 'BEGIN {
       OFMT = "%.0f" # print numbers as integers (rounds)
       print 17.23, 17.54 }'
17 18

Die Anweisung "printf" für ausgefallenere Ausgaben

Zur genaueren Steuerung des Ausgabeformats wird die Anweisung "printf" verwendet. Damit kann die Breite jeder Ausgabe bestimmt werden und ausserdem auch die Formatierung von Zahlen (Exponenten, Zeichen, Anzahl Stellen nach dem Komma). Zu diesem Zweck wird eine "Formatierungszeichenkette" mitgegeben, die sehr ähnlich zu der der ISO C Bibliotheksfunktion "printf" aussieht.

Eine einfache "printf"-Anweisung lautet wie folgt.

printf Formatierungszeichenkette, Element1, Element2, ...

Die ganze Liste von Argumenten kann bei Bedarf auch in Klammern eingeschlossen werden. Zwingend sind diese Klammern, wenn irgendeiner der Ausdrücke in den Elementen das Zeichen ">" als relationalen Operator enthält, das sonst als Umleitung gedeutet wird.

"printf" hängt nicht automatisch einen Zeilenumbruch an seine Ausgabe an sondern gibt nur aus, was die Formatierungszeichenkette angibt; ein Zeilenumbruch muss also wenn gewünscht ebenfalls mit angegeben werden. Die Ausgabetrennervariablen "OFS" und "ORS" haben keine Auswirkung auf "printf"-Anweisungen. Im folgenden Beispiel werden also weder "Autsch!" noch das Zeichen "+" ausgegeben.

$ awk 'BEGIN {
ORS = "\nAutsch!\n"; OFS = "+"
msg = "Keine Panik!"
printf "%s\n", msg
}'
Keine Panik!

Formatsteuerungsbuchstaben

Ein Formatbezeichner beginnt mit dem Zeichen "%", endet mit einem Formatsteuerungsbuchstaben und sagt der "printf"-Anweisung, wie ein Element ausgegeben werden soll. Der Formatsteuerungsbuchstabe bestimmt, welche Art von Wert auszugeben ist. Der Rest des Formatbezeichners besteht aus optionalen "modifiers", die steuern wie der Wert auszugeben ist, z. B. die Feldbreite.

Bedeutung Beispiel
%c Ausgabe einer Zahl als ASCII-Zeichen. Ausgabe des Buchstabens "A".
printf "%c", 65 
%d
%i
Ausgabe einer dezimalen Zahl. Der Bezeichner "%i" existiert aus Kompatibilitätsgründen zu ISO C.
%e
%E
Ausgabe einer Zahl in wissenschaftlicher (exponentialer) Schreibweise. "%E" verwendet "E" anstatt "e" in der Ausgabe. Ausgabe von "1.950e+03" mit vier siginifikanten Zeichen, davon drei nach dem Dezimalpunkt. "4.3" bezeichnet zwei "modifiers".
printf "%4.3e\n", 1950
%f Ausgabe einer Zahl in Fliesskommaschreibweise. Ausgabe von "1950.000" mit gesamt vier signifikanten Zeichen, wovon drei nach dem Komma folgen. "4.3" bezeichnet zwei "modifiers".
printf "%4.3f", 1950
%g
%G
Ausgabe einer Zahl entweder in wissenschaftlicher Schreibweise oder in Fliesskommaschreibweise, je nach dem welcher weniger Zeichen verwendet. Falls das Ergebnis in wissenschaftlicher Schreibweise geschrieben wird, verwendet "%G" ein grosses "E" anstatt "e".
%o Ausgabe einer Oktalzahl.
%s Ausgabe einer Zeichenkette.
%u Ausgabe einer Dezimalzahl. Die Verwendung ist selten, da in awk alle Zahlen als Fliesskommazahlen angesehen werden. Der Bezeichner existiert aus Kompatibilitätsgründen zu ISO C.
%x
%X
Ausgabe einer Hexadezimalzahl. "%X" verwendet dabei die Grossbuchstaben "A" bis "F" anstatt "a" bis "f".
%% Das ist zwar kein Formatbezeichner, gibt jedoch das Zeichen "%" aus.

"Modifiers" für "printf"-Formate

Eine Formatbezeichnung kann auch "modifiers" enthalten, die steuern, wieviel von den Werten des Elements ausgegeben wird und wieviel Raum dafür verwendet wird. Die "modifiers" stehen zwischen dem "%"-Zeichen und dem Formatsteuerungsbuchstaben.

Modifier Bedeutung Beispiel
N$ Eine Zahlenkonstante gefolgt von einem "$"-Zeichen ist ein Positionsbezeichner. Normalerweise werden Formatbezeichnungen in der Reihenfolge auf die Argumente angewendet, in der sie in der Formatierungskette vorkommen. Mit einem Positionsbezeichner wird die Formatbezeichnung auf ein bestimmtes Argument angewendet, anstatt auf das nächste Argument in der Liste. Positionsbezeichner beginnen ihre Zählung bei "1".
printf "%s %s\n", "Keine", "Panik"
printf "%2$s %1$s\n", "Panik", "Keine"
- Das Minuszeichen richtet das Argument nach links aus, falls es vor einem Breite-"modifier" verwendet wird. Normalerweise (also ohne Minuszeichen) erfolgt die Ausrichtung nach rechts. Ausgabe von "foo♦".
printf "%-4s", "foo"
Leerschlag Für Umwandlungen von Zahlen müssen positive Werte mit einem Leerschlag, negative mit einem Minuszeichen eingeleitet werden.
+ Das Pluszeichen (wenn es vor dem Breite-"modifier" verwendet wird) liefert immer ein Zeichen für Zahlenumwandlungen, sogar dann, wenn die zu formatierenden Daten positiv sind. Das Zeichen "+" überschreibt dabei den Leerschlag-"modifier".
# Verwendung einer alternativen Form für bestimmte Steuerungszeichen:
  • Für "%o" wird eine führende "0" geschrieben.
  • Für "%x" und "%X" wird eine führende "0x" bzw. "0X" geschrieben.
  • Für "%e", "%E" und "%f" enthält das Ergebnis immer einen Dezimalpunkt.
  • Für "%g" und "%G" werden führende "0"-Zeichen nicht aus dem Ergebnis entfernt.
Breite Eine Zahl, welche die gewünschte Mindestbreite eines Feldes angibt. Das Einfügen einer Zahl zwischen dem "%"-Zeichen und dem Formatsteuerungsbezeichner zwingt das Feld, sich über mindestens diese Breite auszudehnen. Standardmässig wird das durch Einfügen von Leerzeichen auf der linken Seite erreicht. Wird diese Breitenangabe durch ein Minuszeichen eingeleitet, so werden allfällig nötige Leerzeichen auf der rechten Seite anstatt auf der linken eingefügt. Ausgabe von "♦foo".
printf "%4s", "foo"

Sollte der im Feld enthaltene Wert grösser sein, so dehnt sich das Feld auch über die angegebene Mindestbreite aus. Ausgabe von "foobar".

printf "%4s", "foobar"
.N Ein Punkt gefolgt von einer Zahlenkonstante bezeichnet die Genauigkeit, die bei der Ausgabe verwendet werden soll. Die Bedeutung der Genauigkeit hängt vom jeweiligen Formatbezeichnungsbuchstaben ab.
  • Für "%e", "%E" und "%f" wird die Genauigkeit rechts vom Dezimalpunkt angegeben.
  • Für "%g" und "%G" wird die maximale Anzahl von signifikanten Zahlen angegeben.
  • Für "%d", "%i", "%o", "%u", "%x" und "%X" wird die minimale Anzahl auszugebender Zahlen angegeben.
  • Für "%s" wird die maximale Anzahl von Zeichen angegeben, die ausgegeben werden sollen.
Ausgabe von "foob".
printf "%.4s", "foobar"

Die Fähigkeit der dynamischen Breite und Genauigkeit der C-Bibliothek-Anweisung "printf" (z. B. "%*.*s") wird unterstützt. Anstatt die Breite und Genauigkeit in der Formatzeichenkette anzugeben, werden sie in der Argumenteliste übergeben.

Folgende Schreibweisen erzeugen dasselbe Ergebnis und geben "♦♦abc" aus.

w = 5
p = 3
s = "abcdefg"
printf "%*.*s\n", w, p, s

s = "abcdefg"
printf "%5.3s\n", s

Beispiele für "printf"-Anweisungen

Ausgabe der Namen ("$1") der Bulletin Board-Liste "bbslist" als Zeichenkette von jeweils zehn nach links ausgerichteten Zeichen. ZUsätzlich wird die Telefonnummer ("$2") ausgegeben.

$ awk '{ printf "%-10s %s\n", $1, $2 }' bbslist
aardvark   555-5553
alpo-net   555-3412
...

Im vorherigen Beispiel muss die Telefonnummer als Zeichenkette ausgegeben werden, weil die Zahlen durch Bindestriche getrennt sind. Würden diese Telefonnummern als Zahlen ausgegeben, so würden nur die ersten drei Ziffern ausgegeben ("555").

$ awk '{ printf "%-10s %\n", $1, $2 }' bbslist
aardvark   555
alpo-net   555
...

Die Tabelle kann mit Überschriften angereichert werden.

$ awk 'BEGIN { print "Name       Nummer"
               print "----       ------" }
       { printf "%-10s %s\n", $1, $2 }' bbslist
Name       Nummer
----       ------
aardvark   555-5553
alpo-net   555-3412
...

Anstatt einer Mischung von "print"- und "printf"-Anweisungen kann auch ausschliesslich "printf" verwendet werden. Dabei wird jede Spaltenüberschrift mit derselben Formatbezeichnung wie die Spaltenelemente ausgegeben.

$ awk 'BEGIN { printf "%-10s %s\n", "Name", "Nummer"
               printf "%-10s %s\n", "----", "------" }
       { printf "%-10s %s\n", $1, $2 }' bbslist
Name       Nummer
----       ------
aardvark   555-5553
alpo-net   555-3412
...

Die dreimal verwendete Formatanweisung ("%-10s %s\n") kann in einem solchen Fall auch in eine Variable geschrieben werden.

$ awk 'BEGIN { format = "%-10s %s\n"
               printf format, "Name", "Nummer"
               printf format, "----", "------" }
       { printf format, $1, $2 }' bbslist
Name       Nummer
----       ------
aardvark   555-5553
alpo-net   555-3412
...

Umleitung der Ausgabe von "print" und "printf"

Oft wird die Ausgabe der Anweisungen "print" und "printf" auf der Standardausgabe angezeigt, also am Bildschirm. Die Ausgabe der beiden Anweisungen kann aber auch anderswohin umgeleitet werden. Es gibt vier Formen der Ausgabeumleitung.

Ausgabe in eine Datei

Ausgabe in die Datei "outputfile". Der Dateiname kann dabei auch irgendein Ausdruck sein. Sein Wert wird in eine Zeichenkette umgewandelt und dann als Dateiname verwendet.

print Elemente > outputfile

Bei dieser Art der Umleitung wird die Datei "outputfile" gelöscht, bevor die erste Ausgabe in die neue Datei "outputfile" hineingeschrieben wird. Folgende Schreibvorgänge schreiben in dieselbe Datei, löschen sie also (anders als in der Shell) nicht, sondern hängen an.

$ awk '{ print $2 > "telefonliste"
         print $1 > "namensliste" }' bbslist
$ cat telefonliste
555-5553
555-3412
...
$ cat namensliste
aardvark
alpo-net
...

Ausgabe angehängt an eine Datei

Anhängen der Ausgabe an die bereits vorhandene Datei "outputfile". Sollte die Datei nicht bereits vorhganden sein, so wird sie angelegt.

print Elemente >> outputfile

Ausgabe durch eine Pipeline an einen anderen Befehl

Die Ausgabe kann auch durch eine Pipeline an einen anderen Befehl weitergegeben werden. Dabei wird eine Pipeline zum Befehl geöffnet und die Wert der angegebenen Elemente werden durch diese Pipeline an den Prozess weitergereicht, der durch den angegebenen Befehl gestartet wird. Das Umleitungsargument "command" ist dabei ein awk_Ausdruck, d. h. sein Wert wird in eine Zeichenkette umgewandelt, deren Inhalt den auszuführenden Shell-Befehl ergibt.

print Elemente | command

Das folgende Beispiel erzeugt zwei Dateien: eine unsortierte Liste von BBS-Namen und eine Liste, die in umgekehrter alpabetischer Reihenfolge sortiert ist. Die unsortierte Liste wird dabei über eine gewöhnlichen Umleitung erzeugt, während die sortierte Liste durch Weitergabe an den Befehl sort erzeugt wird.

$ awk '{ print $1 > "namen.unsortiert"
         command = "sort -r > namen.sortiert"
         print $1 | command }' bbslist
$ cat namen.unsortiert
aardvark
alpo-net
...
$ cat namen.sortiert
sdace
sabafoo
...

Das folgende Beispiel verschickt eine Nachricht an die Mailingliste "bug-system". Das könnte sinnvoll sein, wenn awk regelmässig zu Systembetreuungszwecken ausgeführt wird. Die Nachricht wird dabei durch Aneinanderhängen von Zeichenketten zusammengebaut und in der Variable "m" gespeichert. Danach wird sie durch die Pipeline an den Befehl mail geschickt. Die Funktion "close" wird hier verwendet, um die Pipeline wieder zu schliessen, nachdem die beabsichtigte Ausgabe weitergereicht wurde.

$ awk '{ report = "mail bug-system"
print "awk-Skript versagte:", $0 | report
m = ("at record number " FNR " of " FILENAME)
print m | report
close(report) }' bbslist

Die erzeugte und verschickte Mail sieht dann wie folgt aus:

From abc@xyz  Mon Nov 19 15:39:17 2007
X-Original-To: abc
To: abc@xyz
Date: Mon, 19 Nov 2007 15:39:17 +0100 (CET)
From: abc@xyz (Hans Muster)

awk-Skript versagte: aardvark     555-5553     1200/300          B
at record number 1 of bbslist

Eine besonders nützliche Art der Verwendung von Umleitungen ist es, Befehlszeilen zusammenzubauen und diese an die Shell weiterzureichen. Beispielsweise hat man eine Liste von Dateien aus einem System, wo alle Dateinamen in Grossbuchstaben geschrieben wurden, und man möchte diese in Kleinbuchstaben umwandeln. Die Funktion "tolower" gibt ihr Argument mit allen Zeichen in Grossbuchstaben umgewandelt in Kleinbuchstaben zurück. Das Programm baut eine Liste von Befehlszeilen, welche den Befehl mv zum Umbenennen von Dateien verwenden. Danach wird die Liste über eine Pipeline zur Ausführung an die Shell weitergereicht.

{ printf("mv %s %s\n", $0, tolower($0)) | "bash" )
END { close("bash") }

Ausgabe an einen Koprozess

Diese Art der Umleitung gibt die Elemente an die Eingabe des angegebenen Befehls "command" aus. Der Unterschied zur Umleitung, die nur den senkrechten Strich ("|") verwendet besteht darin, dass die Ausgabe von "command" mit "getline" gelesen werden kann. "command" ist also ein Koprozess, der in ergänzender Weise mit awk zusammenarbeitet.

print Elemente |& command

Besondere Dateinamen in gawk

gawk bietet eine Anzahl von besonderen Dateinamen, die intern interpretiert werden. Diese Dateinamen bieten Zugang zu den Standarddateideskriptoren, prozessabhängigen Informationen und TCP/IP-Netzwerkkommunikation.

Bei der Verwendung dieser besonderen Dateinamen sollte folgendes beachtet werden:

  • Die Erkennung der besonderen Dateinamen ist im Kompatibilitätsmodus abgeschaltet.
  • Die prozessbezogenen besonderen Dateinamen werden als veraltet erachtet und werden in Zukunft nicht mehr unterstützt. Stattdessen können prozessbezogene Informationen über das Array "PROCINFO" beschafft werden.
  • A gawk 3.1 werden diese besonderen Dateinamen immer interpretiert. Beispielsweise wird bei Verwendung von "/dev/fd/4" für die Ausgabe tatsächlich auf den Dateideskriptor 4 geschrieben. Meistens macht das nichts; es ist aber wichtig, dass Dateien, die sich auf die Dateisdeskriptoren 0, 1 oder 2 beziehen nicht geschlossen werden, da es sonst zu unvorhersehbarem Verhalten kommen kann.

Besondere Dateien für Standarddeskriptoren

Laufende Programme haben üblicherweise Zugriff auf drei Eingabe- und Ausgabeströme: "standard input" (stdin), "standard output" (stdout) und "standard error output" (stderr). Diese Ströme sind im Standard mit dem Bildschirm verbunden, jedoch werden sie oft über die Operatoren "<", "<<", ">", ">>" und ">&" umgeleitet.

In anderen Implementationen von awk kann eine Fehlermeldung aus awk nur wie folgt an stderr geschrieben werden. Dabei wird eine Pipeline zu einem Shellbefehl geöffnet, der auf den Ausgabestrom stderr zugreifen kann, den er von awk vererbt bekommt.

print "Schlimmer Fehler entdeckt!" | "cat 1>&2"

Weil das unschön und ineffizient ist, werden Fehlermeldungen oft auf den Bildschirm ausgegeben. Das hat normalerweise dieselbe Wirkung. Falls aber die Standardfehlerausgabe nicht auf den Bildschrim zeigt (da sie ja umgeleitet werden kann) versagt diese Methode, da dann nicht auf "/dev/tty" geschrieben werden kann.

print "Schlimmer Fehler entdeckt!" > "/dev/tty"

gawk bietet besondere Dateinamen für den Zugriff auf die drei Standardströme sowie beliebige andere vererbte und geöffnete Dateien. Wenn der Dateiname bei der Umleitung von Ein- oder Ausgabe mit einem dieser besonderen Dateinamen übereinstimmt, so wird direkt der Strom verwendet, für den diese Datei steht.

/dev/stdin Standardeingabe (Dateideskriptor 0).
/dev/stdout Standardausgabe (Dateideskriptor 1).
/dev/stderr Standardfehlerausgabe (Dateideskriptor 2).
/dev/fd/N Die mit dem Dateideskriptor N verbundene Datei. Eine solche Datei muss durch das Programm (üblicherweise die Shell) geöffnet werden, welches awk ausführt. Ohne besondere Einrichtungen stehen nur die Dateideskriptoren 0, 1 und 2 zur Verfügung. Die Dateinamen "/dev/stdin", "/dev/stdout" und "/dev/stdout" sind also nur Aliase für "/dev/fd/0", "/dev/fd/1" und "/dev/fd/2".

Die saubere Art, um in gawk eine Fehlermeldung zu schreiben lautet also wie folgt. Dabei muss der Dateiname wie bei anderen Umleitungen in Anführungszeichen gesetzt werden, da sonst verwirrende Ergebnisse auftreten können.

print "Schlimmer Fehler entdeckt!" > "/dev/stderr"

Besondere Dateien für prozessbezogene Informationen

gawk bietet besondere Dateinamen, die den Zugriff auf Informationen über den laufenden gawk-Prozess ermöglichen. Jede dieser "Dateien" bietet einen eigenen Datensatz von Informationen. Um sie mehr als einmal zu lesen, müssen sie zuvor mit der Funktion "close" geschlossen werden. Allerdings sollen diese Dateinamen in zukünftigen Versionen von gawk ganz verschwinden - stattdessen können prozessbezogene Informationen über das Array "PROCINFO" beschafft werden (siehe Effective awk programming Kapitel 6).

Diese besonderen Dateinamen können einerseits auf der Befehlszeile als Datendateien verwendet werden, andererseits auch für I/O-Operationen innerhalb von awk. Sie sollten aber nicht als Quelldateien mit der Option "-f" verwendet werden.

/dev/pid Lesen dieser Datei gibt die Prozess-ID (PID) des aktuellen Prozesses in dezimaler Form aus, beendet durch einen Zeilenumbruch.
/dev/ppid Lesen dieser Datei gibt die Eltern-Prozess-ID (PPID) des aktuellen Prozesses in dezimaler Form aus, beendet durch einen Zeilenumbruch.
/dev/pgrpid Lesen dieser Datei gibt die Prozess-Gruppen-ID des aktuellen Prozesses in dezimaler Form aus, beendet durch einen Zeilenumbruch.
/dev/user Lesen diese Datei gibt einen einzelnen Datensatz aus, beendet durch einen Zeilenumbruch. Die Felder stehen für folgende Informationen:
  • "$1" steht für den Rückgabewert des Systemaufrufs "getuid" (die reale Benutzer-ID-Nummer).
  • "$2" steht für den Rückgabewert des Systemaufrufs "geteuid" (die tatsächliche Benutzer-ID-Nummer).
  • "$3" steht für den Rückgabewert des Systemaufrufs "getgid" (die reale Gruppen-ID-Nummer).
  • "$4" steht für den Rückgabewert des Systemaufrufs "getegid" (die tatsächliche Gruppen-ID-Nummer).

Falls es zusätzliche Felder gibt, so handelt es sich um die Gruppen-ID-Nummern, die vom Systemaufruf "getgroup" zurückgegeben werden.

Besondere Dateien für Netzwerkkommunikation

Ab gawk 3.1 können awk-Programme eine bidirektionale TCP/IP-Verbindung öffnen, wobei sie entweder als Client oder als Server auftreten. Dies wird durch Verwendung eines besonderen Dateinamens der folgenden Form erreicht. "protocol" kann dabei die Werte "tcp", "udp" oder "raw" haben. Die anderen Felder stehen für die übrigen Informationen, die zum Aufbau einer Netzwerkverbindung benötigt werden.

/inet/protocol/local-port/remote-host/remote-port

Diese Dateinamen werden mit dem Operator "|&" zur Kommunikation mit einem Koprozess verwendet.

Weiteres dazu siehe Effective awk programming Kapitel 10 und 14.