UNIX Praktische Helfer
aus: Wie werde ich UNIX-Guru
und: UNIX-Das umfassende Handbuch
Willemers Informatik-Ecke
UNIX liefert eine Menge Werkzeuge, um mit Textdateien umzugehen. Man kann mit Bordmitteln fast beliebige Informationen aus Textdateien gewinnen und in beinahe unbegrenzter Form wieder zusammensetzen.

Viele Werkzeuge für Textdateien

UNIX arbeitet sehr intensiv mit Textdateien, gerade im Bereich der Konfiguration und Administration. Diese an sich einfache Methode ermöglicht das leichte Auffinden von Fehlern. Es hat aber auch ungeheure Vorteile, wenn es darum geht, eine Installation zu dokumentieren, zu sichern und zu prüfen. Man kann Textdateien leicht ausdrucken oder kopieren. Manipulationen am System sind schnell erkannt und können so leicht beseitigt werden.

Ausgabe einer Datei: cat

Der Befehl cat zeigt den Inhalt von Dateien auf dem Bildschirm an, die ihm als Argumente angegeben werden. cat ist die Abkürzung für concatenate, also Aneinanderhängen. Durch eine Umleitung der Ausgaben, kann aus mehreren Dateien eine zusammengängende gemacht werden. Man kann dies auf dem Bildschirm sehen, wenn man mehrere Dateien hinter dem Befehl cat angibt. Folgender Befehl zeigt zweimal hugo und einmal erna direkt hintereinander an.

cat hugo hugo erna

Seitenweise: more

Um eine Datei anzuzeigen, deren Inhalt größer als der Bildschirm ist, verwendet man das Programm more. Es zeigt die Datei an und stoppt die Ausgabe am unteren Bildschirmrand. Mit der Leertaste kann man seitenweise, mit der Returntaste zeilenweise weiterblättern. Mit q kann man die Ansicht vorzeitig verlassen.

less entspricht more

Auf manchen Systemen wird das Programm less eingesetzt. Der Name stammt aus der Wortspielerei "less is more than more". Mit less kann man beispielsweise mit dem Buchstaben b auch rückwärts blättern. Auf vielen Systemen funktionieren sogar die Cursortasten zum Bewegen innerhalb des Textes.

Suche nach Stichworten

Neben den einfachen Blätterfunktion ist es auch möglich, Textstellen zu suchen. Wie beim vi verwendet man den Schrägstrich. Der Cursor geht hier wie dort in die unterste Zeile und erwartet einen Suchbegriff. Allerdings verarbeitet more keine regulären Ausdrücke. Die nächste Fundstelle erreicht man wie bei vi mit einem n.

Durchsuchungsbefehl: grep

Der Befehl grep dient dazu, aus einer oder mehreren Dateiinhalten eine bestimmte Zeichenkette herauszusuchen und anzuzeigen. Der erste Parameter von grep ist das Suchmuster. Es folgen die zu durchsuchenden Dateien. Wurden mehrere Dateien angegeben, wird bei der Ausgabe der Ergebnisse auch der Dateiname ausgegeben.

Beispielsweise kann man in einem Projekt in C ermitteln, welche Module eine bestimmte Funktion (als Beispiel printf) verwenden. Zu diesem Zweck gibt man ein:

grep  printf  *.c

Suchbegriffe mit Leerzeichen setzt man in Anführungszeichen oder Hochkommata.

Optionen von grep

-h unterdrückt die Dateianzeige

Der Befehl grep hat einige wichtige Optionen. Mit der Option -h (h wie hide engl. verstecken) wird die Anzeige der Dateinamen unterdrückt. Das ist wichtig, wenn die ausgefilterten Ausgaben von anderen Programmen weiterverarbeitet werden sollen.

-v invertiert die Ausgabe

Die Option -v invertiert die Suche. Das heißt, es werden die Zeilen angezeigt, in denen das Muster eben nicht enthalten ist.

-w nur Worte

Die Option -w legt fest, dass das Suchmuster ein vollständiges Wort darstellt. Worte werden durch Leerräume und Sonderzeichen begrenzt.

-i ignoriert groß und klein

Mit der Option -i kann die Beachtung von Groß- und Kleinschreibung aufgehoben werden. Die Suche nach einer hose findet dann auch Hose, HOSE und hose.

-c zählt nur

Mit der Option -c (c wie count engl. zählen) werden die Zeilen gar nicht ausgegeben, sondern es wird nur ermittelt, wie oft das Suchmuster in den Dateien vorkommt.

Wenn ich auf das Ende sehe: tail

Mit dem Kommando tail kann man sich die letzten Zeilen einer Datei anzeigen lassen. Als Argument wird die anzuzeigende Datei angegeben. Die Anzahl der Zeilen, die angezeigt wird, kann durch ein Minus gefolgt von der Zahl der Zeilen angegeben werden. Standard sind 10 Zeilen.

tail -f verfolgt Dateiveränderungen

Ein wichtiger Einsatz von tail ist das Beobachten sich verändernder Dateien, wie beispielsweise Logfiles. Will man die messages-Datei beobachten, gibt man beispielsweise ein:

tail -f /var/log/messages

Alle Daten, die in diese Datei flie"sen, erscheinen nun auch auf dem Terminal. Durch die Delete-Taste oder ctrl-C (je nachdem, was auf dem lokalen System als Break-Taste definiert ist) kann der tail-Befehl wieder gestoppt werden.

Analog zu tail gibt es auch ein Programm head, das die ersten Zeilen einer Datei anzeigt. Seine praktische Bedeutung ist aber geringer, weil es sehr viel häufiger vorkommt, dass man die letzten Einträge einer Protokolldatei sehen will als die ersten.

Wortzähler: wc

auch Zeilen und Zeichen zählen

Dieses Programm mit dem eingängigen Namen (wc steht allerdings eigentlich für wordcount) zählt die Wörter in einer Datei. Wer nicht weiß, welchen Nutzen es ihm bringen soll, wenn er die Anzahl der Worte in seinem C-Programm ermitteln kann, wird vielleicht eher eine Anwendung finden, wenn er weiß, dass das Programm mit der Option -l auch Zeilen und mit der Option -c Buchstaben zählt.

sort

Mit dem Befehl sort wird eine Datei sortiert auf dem Bildschirm ausgegeben. Wird kein weiterer Parameter angegeben, sortiert sort die Datei Zeile für Zeile nach ihren Anfängen in alphabethischer Reihenfolge. Besonders interessant ist dieses Programm natürlich dadurch, dass man die Ausgabe wieder in eine Datei umleiten kann und weiterverarbeiten kann.

Die wichtigsten Optionen sind -r für das Umkehren der Reihenfolge, -f für das Ignorieren von Klein- und Großschreibung und -n für die numerische Sortierung von Zahlen.

Datenstromeditor sed

sed wird in Pipes eingesetzt

sed ist das Kürzel für stream editor. Man könnte das mit Datenstromtextverarbeitung übersetzen. Das Programm wird hauptsächlich im Zusammenhang mit Pipes als Filter eingesetzt. Fast immer wird die Option -e angegeben, die Befehle auf den Datenstrom anwendet. Ein Befehl von sed hat folgenden Aufbau: Zunächst wird der Bereich, in dem der Befehl wirkt, genannt. Es folgt der Befehlsname und schließlich folgen, falls erforderlich, die Argumente des Befehls.

Suchen und Ersetzen

Der Wirkungsbereich wird wie bei vi in der Befehlszeile beschrieben. Der Aufbau ist Anfangszeile, dann ein Komma, gefolgt von der Endzeile. Dabei steht das Dollarzeichen für die letzte Zeile. Auch den Befehl zum Suchen und Ersetzen, der im vi schon soviel Bewunderung auslöste, kann hier wiederverwendet werden. Weil es so schön war, nochmal das Beispiel:

1,$ s/suchmuster/ersetze/g

Beispielsweise kann man in einem Text jedes Auftreten von "geil" in "super" ersetzen:

cat teenie.text | sed -e "1,$ s/geil/super/g" > alten.tauglich

Löschen

Man kann Zeilen aus dem Datenstrom mit dem Befehl d herauslöschen. Im Beispiel werden alle Zeilen entfernt, in denen das Stichwort "unfug" auftritt.

cat normal.text | sed -e "/unfug/d" > kluger.text

awk

awk kann Texte auswerten

Das Programm awk ist ein Werkzeug zur Auswertung von Textdateien, die behandelt werden wie Datenbanktabellen. Der Name des Programmes setzt sich aus den Anfangsbuchstaben der Nachnamen seiner prominenten Entwickler Aho, Weinberger und Kernighan zusammen. Das Programm awk ist in der Lage, aus einer Datei Spalten und Zeilen auszuwählen und darüber Auswertungen durchzuführen. Im Grunde ist es ein grep, das um die Fähigkeit erweitert wurde, auf Texte innerhalb der gefundenen Zeilen zuzugreifen, sie in Variablen aufzunehmen und zu verarbeiten. awk besitzt darüber hinaus eine kleine Programmiersprache, sodass auch Fallunterscheidungen oder ähnliches leicht zu realisieren ist.

Wie das aber bei flexiblen und leistungsstarken Programmen so ist, ist man auch leicht von der Komplexität der Möglichkeiten erschlagen. Dennoch lohnt sich ein Blick auf dieses Programm, da es bestimmte Probleme mit erstaunlich wenig Aufwand lösen kann.

Spalten durch Leerzeichen und Tabulatoren

awk betrachtet wie gesagt eine Textdatei als Datenbanktabelle aus Zeilen und Spalten. Die Zeilen sind durch den Zeilentrenner bestimmt, der unter UNIX übrigens mit dem Linefeed codiert wird (ASCII-Zeichen 10). Zwei Spalten werden aus der Sicht von awk und auch anderer UNIX-Werkzeuge durch ein oder mehrere Leerzeichen oder Tabulatorzeichen getrennt.

Suchen wie mit sed

awk kann wie grep Zeilen aus einer Datei anhand eines Suchbegriffes heraussuchen. Dazu wird der Suchbegriff in Schrägstriche eingeschlossen, was wiederum vom sed bekannt vorkommt. In geschweiften Klammern können Spalten ausgegeben werden. Der gesamte Befehl wird wiederum in Hochkommata eingeklammert, damit die Shell nicht daran herumwerkelt. Beispiel:

awk '/Willemer/ {print $3}' telefon

Dieser Befehl gibt für alle Zeilen der Datei telefon, in denen die Zeichenfolge Willemer steht, die dritte Spalte aus. Die Datei telefon ist eine einfache Textdatei, in der Name, Vorname und Telefonnummer in jeder Zeile stehen. Im folgenden sehen Sie einen kurzen Ausschnitt:

Müller Anton 0987-6543
Schmidt Erwin 01234-5678
Willemer Arnold 04632-110

Das Hochkomma

Im Allgemeinen bestehen die Argumente von awk aus mehr als einem Wort. Da die Shell durch Leerzeichen getrennte Eingaben dem Programm separat übergibt, wird ein Argument, das aus mehreren Worten besteht, in Anführungszeichen oder in Hochkommata eingeschlossen. Diese sind auch hilfreich, wenn das Kommando über mehrere Zeilen geht, da die Shell den Befehl erst als abgeschlossen ansieht, wenn das zweite Hochkomma erscheint. Man verwendet übrigens bei awk das Hochkomma statt dem Anführungszeichen, da die Shell in Anführungszeichen auch Umgebungsvariablen auswertet. Das wird durch Hochkommata ausgeschlossen.

Selektion: Auswahl von Zeilen

Suchbegriff zwischen / selektiert Zeilen

Das Kommando zur Selektion wird gegeben, indem der Suchstring in Schrägstriche gesetzt wird. Unter einer Selektion versteht man die Auswahl der Zeilen einer Tabelle.

awk /Willemer/ telefon

Alle Zeilen mit der Zeichfolge Willemer in der Datei telefon werden ausgegeben. Wird kein Suchstring angegeben, werden alle Zeilen angezeigt. Im Suchbegriff können reguläre Ausdrücke verwendet werden.

Würde die Datei telefon alle Telefonnummern enthalten, würde nach der Ausführung des Befehls meine gesamte Verwandtschaft einträchtig beisammen stehen, wie das im Leben vielleicht nicht der Fall wäre. Sind Computer nicht etwas wunderbares?

Projektion: Auswahl von Spalten

Geschweifte Klammern

Zur Projektion muss die Spalte angegeben werden und ein Kommando, was mit ihr passieren soll. Als Spaltentrenner gilt jede beliebige Kombination von Tabulatorzeichen oder Leerzeichen. Das einfachste Kommando ist die Ausgabe mittels print. Die Spalte wird durch deren Nummer und ein vorgestelltes Dollarzeichen bezeichnet. Die Zählung beginnt bei 1, da $0 die gesamte Zeile bezeichnet. Aktionen werden immer in gescheifte Klammern gesetzt. Die dritte Spalte einer Datei wird also folgendermaßen ausgegeben:

awk '{print $3}'

Es ist möglich, mehrere Befehle in einer geschweiften Klammer zu setzen. Dabei sind die Kommandos je durch ein Semikolon zu trennen.

Kombination von Kommandos

Die Kombination beider Optionen ist möglich.

awk '/Willemer/ {print $3}' telefon

Das bereits bekannte Beispiel selektiert also nach der Zeichenfolge Willemer und führt in allen Zeilen, auf die die Selektion zutrifft, den Inhalt der geschweiften Klammer aus. Dieser besagt, dass die dritte Spalte ausgegeben werden soll.

Variablen

Innerhalb des awk-Kommandos können Variablen verwendet werden. Variablen sind dem Programmierer aus den Programmiersprachen vertraut. Es sind einfach Speicherplätze für Informationen wie Zahlen oder Zeichenfolgen. Um auf diese Speicher zugreifen zu können, verwendet man Namen. Solche Variablen kennt auch awk und können beispielsweise zur Bildung von Summen eingesetzt werden. Eine Deklaration, wie in vielen Programmiersprachen, ist nicht erforderlich.

Auch die Shell kennt Variablen, wie später näher betrachtet wird. Im Gegensatz zu den Umgebungsvariablen der Shell wird den Variablen von awk kein Dollarzeichen zur Auswertung vorangestellt. Im folgenden Beispiel ist anzahl eine Variable, die dort zum Zählen der Tage verwendet wird.

Start-, Standard- und Endanweisungen

Man kann drei Typen von Anweisungen unterscheiden. Die Standardanweisung wurden bereits vorgestellt. Dieser Typ wird auf jede selektierte Zeile angewandt. Daneben gibt es noch die Startanweisung, die genau einmal vor der ersten Verarbeitung ausgef"uhrt wird und das Schlüsselwort BEGIN voranstellt. Die Endanweisung wird durch das Schlüsselwort END eingeleitet. Hier ein Beispiel:

gaston> awk 'BEGIN{print"Wir zählen Tage!"; anzahl=0}
     {print $1;anzahl++}
     END{print "Das waren " anzahl " Tage"}' tage
Wir zählen Tage!
montag
dienstag
mittwoch
donnerstag
freitag
samstag
sonntag
Das waren 7 Tage
gaston>

Die Datei tage enthält in der ersten Spalte die Wochentage. Bei BEGIN wird die lokale Variable anzahl auf Null gesetzt. Das ist allerdings an sich nicht nötig, da Variablen bei awk standardmäßig mit Null vorbesetzt sind. In der Standardanweisung wird nicht nur die erste Spalte ausgegeben, sondern parallel dazu die Variable anzahl um eins erhöht. Die END-Anweisung wird benutzt, um die Anzahl der Tage auszuwerfen.

Ein weiteres Beispiel soll die Summe aller Dateilängen mit der Endung gnt bilden. In diesem Fall wird awk an eine Pipe gehängt. Man gibt in der ersten Zeile das Kommando, um ein Verzeichnis in seiner Langform anzusehen. Das Ergebnis wird dem awk per pipe zugeschoben. In der Standardanweisung des awk wird eine Variable um den Wert in der fünften Spalte erhöht. Die Endanweisung gibt diese Variable aus.

ls -l *.gnt | awk '{sum+=$5}END{print sum}'

Die Suche nach gnt könnte natürlich auch von awk übernommen werden. Dann hie"se der Befehl:

ls -l  | awk '/gnt/ {sum+=$5} END{print sum}'

Der Unterschied besteht darin, dass in diesem Fall Zeilen, in denen irgendwo gnt (beispielsweise im Gruppennamen) vorkommt, auch mitgerechnet werden.

Eingebaute Funktionen

awk hat einige eingebaute Funktionen, die in ihrem Syntax sehr an C erinnern.

Funktion Wirkung
print Anzeigen
printf Entspricht der C-Funktion printf
sprintf für Speicherung von Ausgaben in einer Variablen
length(s) ermittelt die Länge einer Zeichenkette
substr(s, anf, anz) Teilstringbildung
index(s, t) gibt die Stelle an, an der in s die Zeichenkette t beginnt
sqrt(n) Wurzel
log(n) natürlicher Logarithmus
exp(n) $e^n$
int(n) ganzzahliger Anteil

Ausführung von Programmdateien

Mit den Variablen und Befehlen kann man komplexe Programme erzeugen. Damit diese nicht jedesmal neu eingegeben werden m"ussen, kann man Dateien mit den auszuführenden Aktionen schreiben. Diese sind dann mit der Flag -f statt des Kommandos aufzurufen.

awk -f awkprg

In diesem Beispiel stehen in der Datei awkprg die Befehle, die durch awk abgearbeitet werden sollen.

Weitere Werkzeuge im Überblick

Es gibt noch eine Reihe sehr praktischer kleiner Werkzeuge. Häufig sind es kleine Programme, die sehr spezielle Aufgaben lösen. Sie sind manchmal beinahe unbekannt, aber vielleich in der einen oder anderen Situation hilfreich. Da sie zugegebenermaßen ein wenig exotisch sind, sollen hier nur tabellarisch aufgezählt werden.

Programm Funktion
split teilt eine große Textdatei in mehrere kleine auf
cut schneidet einen angegebenen Teil aus einer Datei heraus
fold bricht Zeilen ab einer bestimmten Zeilenlänge um
tr wandelt Zeichen von stdin nach stdout um
diff zeigt die Unterschiede zwischen zwei Textdateien

Genauere Informationen finden sich in den passenden Manpages.

Diese Seite basiert auf Inhalten aus dem Buch Arnold Willemer: Wie werde ich UNIX-Guru?