Eine der Stärken von Unix und damit auch von Linux ist die Vielfalt der Werkzeuge. Für die meisten Aufgaben existieren spezialisierte Programme. In diesem Artikel werden Werkzeuge zur Textsuche vorgestellt.Unix ist für seine Spezialisten bekannt. Für die Suche von Zeichenketten in Textdateien nimmt man üblicherweise »grep«. Es durchsucht die angegebenen Dateien zeilenweise nach dem ebenfalls angegebenen Suchwort. Die Zeilen, in der die angegebene Passage vorkommt, werden angezeigt.
Der Name »grep« stammt vom Zeileneditor »ed«, in dem der Befehl »g/re/p« die Zeilen ausgibt, die das Muster »re« enthalten. Das Muster ist ein regulärer Ausdruck (engl. »regular expression«). Der Befehl bedeutet ausgeschrieben "Global Regular Expression Print".
Es gibt drei GREP-Programme. Neben dem eigentlichen »grep« findet man meistens noch »fgrep« (bzw. »grep -F«) und »egrep« (kompatibel mit, jedoch nicht ganz gleich »grep -E«). »fgrep« steht für »Fixed GREP« und sucht nur nach unveränderlichen Zeichenketten. Der Name »egrep« bedeutet »Extended GREP«. Es werden andere Algorithmen benutzt als beim normalen »grep« und die regulären Ausdrücke werden anders interpretiert. Für viele sind die regulären Ausdrücke von »egrep« leichter zu verstehen. Im Zweifelsfall ist die Manualseite (»man grep«) zu konsultieren.
Die Syntax der Programme ist denkbar einfach. Direkt nach dem Programmnamen werden mögliche Optionen angegeben. Anschließend folgt der erste wichtige Parameter, nämlich das zu suchende Muster, der reguläre Ausdruck. Als nächstes werden die Dateien angegeben, in denen nach dem Muster gesucht werden soll. Es können praktisch beliebig viele Dateien angegeben werden.
Wenn das Suchmuster aus mehreren Wörtern besteht und Leerzeichen enthält oder wenn im Muster Zeichen vorkommen, die in der verwendeten Shell eine besondere Bedeutung haben (z.B. »|« und »\«), dann muß das Muster in Hochkommas gesetzt werden. Der folgende Befehl gibt die Zeilen der Dateien »linux-admin« und »linux-net« aus, in denen das Wort »portmap« vorkommt.
grep portmap linux-admin linux-netIm täglichen Gebrauch wird oft eine Möglichkeit gesucht, bestimmte Zeilen herauszufiltern. GREP unterstützt das und bietet den Parameter »-v« an, der die Bedeutung umkehrt. Der folgende Befehl zeigt demnach alle Zeilen an, in der das angegebene Muster nicht enthalten ist.
grep -v portmap linux-admin linux-net
Für die Benutzung unter Unix ist das Gruppieren von Zeichenketten wichtig. Insbesondere in Verbindung mit der Möglichkeit, Teile des gefundenen Musters zu speichern und/oder auszutauschen, bekommt der Unix-Benutzer ein Werkzeug an die Hand gelegt, das seinesgleichen sucht. Wer einmal angefangen hat, mit »grep«, »sed« und »perl« zu arbeiten, wird es auf anderen Systemen schnell vermissen.
Während man in der DOS-Welt meistens mit einfachen Suchworten zu tun hat, findet man unter Unix fast nur reguläre Ausdrücke. Wer in den wichtigsten Editoren Emacs und VI einen Text sucht, stößt auf reguläre Ausdrücke. Wer variablen Text in einer Datei abschneiden muß, wird »sed« mit einem regulären Ausdruck benutzen. Wer Worte in einem Text ersetzt oder in Textdateien Spalten austauscht, wird reguläre Ausdrücke verwenden.
Reguläre Ausdrücke sind erheblich mächtiger als normale Suchbegriffe. Sie sind daher erheblich flexibler und lassen sich universell einsetzen. Natürlich beinhalten sie auch einfache Suchbegriffe. Einzelne Ausdrücke dürfen zudem zusammengesetzt werden, was einer UND- oder ODER-Verknüpfug gleichkommt, sie dürfen beliebig geschachtelt werden.
Die Kurzreferenz mutet recht technisch an, reguläre Ausdrücke unterliegen jedoch strengen Regeln, nach denen sie gebildet werden. Die Zeichen »a«, »b« und »c« stellen jeweils reguläre Ausdrücke dar. Reguläre Ausdrücke werden nach folgenden Regeln rekursiv gebildet.
| Reguläre Ausdrücke | |
|---|---|
| '' | Die leere Zeichenkette ist ein regulärer Ausdruck, der immer Übereinstimmung findet, was man mit »grep '' foo« leicht überprüft. |
| . | Der Punkt ist ein Platzhalter für exakt ein beliebiges Zeichen, nicht zu verwechseln mit der leeren Zeichenkette. |
| [xyz] | Dieser Ausdruck steht für eins der Zeichen »x«, »y« oder »z«. |
| [^xyz] | Dieser Ausdruck steht für ein beliebiges Zeichen außer »x«, »y« und »z«. |
| \0nn | Nur das Zeichen mit dem gleichen Oktalwert stimmt überein. |
| \xnn | Nur das Zeichen mit dem gleichen Hexadezimalwert stimmt überein. |
| a? | Der Ausdruck »a« kommt kein einziges mal oder genau einmal vor. |
| a* | Der Ausdruck »a« kommt beliebig oft oder keinmal vor. |
| a+ | Der Ausdruck »a« kommt mindestens einmal vor. |
| ab | Die Ausdrücke »a« und »b« stehen direkt nacheinander im Text. |
| a|b | Einer der Ausdrücke »a« oder »b« stimmt mit dem Text überein. |
| (a) | Die runden Klammern gruppieren reguläre Ausdrücke. »a« und »(a)« sind prinzipiell äquivalent. |
| a{n} | Der reguläre Ausdruck muß genau n-mal vorkommen. Wird nur teilweise unterstützt. |
| a{n,m} | Der reguläre Ausdruck muß mindestens n-mal, jedoch höchstens m-mal vorkommen. Wird nur teilweise unterstützt. |
| ^a | Der reguläre Ausdruck muß am Zeilenanfang stehen, darf nur einmal verwendet werden. |
| a$ | Der reguläre Ausdruck muß am Zeilenende stehen, darf nur einmal verwendet werden. |
Um nach Zeichen mit besonderer Bedeutung wie Klammern, Punkt, Fragezeichen u.s.w. zu suchen, muß ihnen ein Backslash vorangestellt werden. Oft werden reguläre Ausdrücke in normale Schrägstriche eingefaßt. Meistens sind die Schrägstriche dabei selbst Platzhalter und können genausogut Doppelpunkte oder Buchstaben sein. Es muß lediglich jeweils das gleiche Zeichen vor und nach dem Ausdruck benutzt werden. Der Vorgang, Übereinstimmungen zu suchen, wird als »Pattern Matching« bezeichnet.
M[ao]rt[ei]na? stimmt mit »Morten«, »Martin«, »Martina«, »Marten«, jedoch auch »Mortena« und »Mortina« überein.
M(orte|arti)n paßt nur auf »Morten« und »Martin«
Th?om(as)? (Ch|K)rist(ia|e)nss?s[eo]n beschreibt »Thomas«, »Thom« oder »Tom Christianssen«, »Christiansson«, »Christenssen«, »Christensson«, mit »K« oder »Ch« sowie mit einem oder zwei »s« im Nachnamen.
»grep« und »egrep« interpretieren reguläre Ausdrücke unterschiedlich. Für »grep« haben runde Klammern und der senkrechte Strich zum Beispiel keine besondere Bedeutung. Sollen sie zur Bildung von regulären Ausdrücken verwendet werden, muß ihnen ein Backslash vorangstellt werden.
Anders bei »egrep«. Hier haben sie automatisch ihre besondere Bedeutung. Wie das jeweilige Programm diese Sonderzeichen behandelt, ist im einzelnen in der beigefügten Dokumentation nachzulesen. Der geneigte Leser möge folgende Zeilen mit geeigneten Ausdrücken ausprobieren, um die Unterschiede zu verdeutlichen.
grep '(portmap|hosts)' datei grep '\(portmap\|hosts\)' datei egrep '(portmap|hosts)' datei egrep '\(portmap\|hosts\)' datei
Wer »grep« in Skripten, also einfachen Programmen, einsetzt, wird teilweise vom Parameter »-q« Gebrauch machen. Damit wird die normale Bildschirmausgabe unterdrückt, der Bildschirm wird also nicht verunstaltet. Anstelle der Textausgabe, die auch mehrzeilig erfolgt, werten Skripte oft die Exit-Codes aus.
Wie jedes andere Unix-Werkzeug liefert auch »grep« 0 zurück, wenn die Bearbeitung erfolgreich war, also mindestens eine Übereinstmmung gefunden wurde. Wurde der Ausdruck nicht gefunden, wird 1 zurückgegeben und 2 im Fehlerfall. Der geneigte Leser mag dieses nachvollziehen:
grep -q joey /etc/password; echo $?Mit »$?« wird in einer Bourne Shell (»/bin/sh«) der Exit-Code des zuletzt gestarteten Programms referenziert.
Martin Schulze