Reguläre Ausdrücke in UNIX

Willemers Informatik-Ecke

Diese Seite basiert auf Inhalten aus dem Buch
Arnold Willemer: Wie werde ich UNIX-Guru
Verlagsrechte bei galileo computing

Für den Suchbegriff kann in vielen UNIX-Programmen wie grep oder vi ein regulärer Ausdruck verwendet werden. Zunächst einmal ist ein regulärer Ausdruck nichts anderes als ein Suchbegriff und man kann ganz naiv den Begriff verwenden, den man sucht. Wenn Sie also das Wort "Maus" suchen, können Sie auch "Maus" als regulären Ausdruck angeben. Reguläre Ausdrücke können komplexeste Suchmuster beschreiben. Dann sehen diese Ausdrücke auf den ersten Blick allerdings etwas erschreckend aus.

Anders als Wildcards

Zunächst werden einfache Platzhalter verwendet. Bei den Dateimasken der Shell, den so genannten Wildcards gibt es solche Platzhalter auch. Die regulären Ausdrücke haben allerdings nichts mit den Wildcards zu tun, die die Shell verwendet. Dort hat der Stern beispielsweise eine andere Bedeutung als hier. Das einfachste Sonderzeichen ist der Punkt. Er steht stellvertretend für genau ein beliebiges Zeichen. Die Suche nach M..s findet die Worte Maus, Moos und Muks, aber nicht Murks, da hier zwischen M und s drei Zeichen stehen. Der Punkt ist also in der Wirkung mit dem Fragezeichen bei den Wildcards vergleichbar.

Multiplikatoren

Der Stern und das Pluszeichen sind Multiplikatoren und beziehen sich immer auf das Zeichen links neben sich. Das Pluszeichen sagt, dass das Zeichen einmal oder mehrfach auftreten kann. Beim Stern ist es auch denkbar, dass das Zeichen gar nicht erscheint. Die Suche nach abc* findet also abc, abcc, abcccccc, aber auch ab. Wirklich interessant werden beide Zeichen in Verbindung mit dem Punkt. So findet M.*s Maus und Moos, aber eben auch Murks und Meeresfrüchte.

Anfang und Ende

Hier werden Sie vielleicht stutzen, denn Meeresfrüchte enden doch gar nicht auf s. Das ist richtig, aber im regulären Ausdruck wurde ja auch gar nicht erwähnt, dass das Wort hinter s enden soll. Das müsste man explizit angeben mit einem \>. Das Gegenstück lautet \< und bedeutet Wortanfang. So wie Wortanfang und -ende gesucht werden kann, so gibt es auch das ^ für den Zeilenanfang und das $ für das Zeilenende. Eine wichtige Anwendung liegt darin, die Verzeichnisse anzeigen zu lassen. Unter UNIX unterscheidet man Dateien von Verzeichnissen an dem kleinen d am Zeilenanfang, wenn man ls -l aufruft. Dementsprechend würde folgende Befehlskombination nur die Verzeichnisse anzeigen:

gaston> ls -l | grep ^d
drwxr-xr-x    3 arnold   users        4096 Jun 25 20:57 pic
drwxr-xr-x    2 arnold   users        4096 Jun 28 20:55 unprog
gaston>

In dem grep wird also ein d gesucht, dass direkt dem Zeilenanfang folgt, oder anders ausgedrückt, das am Anfang der Zeile steht. Ohne das Dach hätte man alle Zeilen erhalten, in denen ein d steht. Da der Benutzer arnold heißt, wären das wohl jede Datei des Verzeichnisses.

Ausdruck Bedeutung
. (Punkt) Steht für ein einzelnes beliebiges Zeichen
[afg] Das Zeichen a, f oder g muss an dieser Stelle erscheinen
[0-9] Eine Ziffer muss an dieser Stelle stehen
* Das vorangehende Zeichen kommt beliebig oft vor
+ Das vorangehende Zeichen kommt mindestens einmal vor
^ Zeilenanfang
$ Zeilenende
\< Wortanfang
\> Wortende
\ Das folgende Zeichen wird nicht als Metazeichen interpretiert
\( \) Markierung eines Bereichs
\1 \2 \dots Referenz auf erste und zweite Markierung

Ersetzen im vi

Vielfältige Möglichkeiten gewinnt man im vi dadurch, dass man als Suchwort einen regulären Ausdruck verwenden kann. Ganz besondere Möglichkeiten tun sich dadurch auf, dass man Markierungen innerhalb eines Ausdrucks setzen kann und diese beim Ersetzen verwenden kann. Ein praktisches Beispiel findet sich beim Umsetzen von TeX-Dokumenten nach HTML. In der ersten Zeile sehen Sie eine Überschrift in TeX und darunter eine in HTML.

\section{Dies ist ein spannendes Kapitel}
<H1>Dies ist ein spannendes Kapitel</H1>

Um alle Vorkommen von section in die entsprechenden <H1> umzuwandeln, wird ein regulärer Ausdruck verwendet. Zunächst wird das Muster beschrieben, das eine section erkennt.

\\section{.*}

Der doppelte Backslash muss sein, damit er nicht als Kommando missinterpretiert wird. In den geschweiften Klammern steht schlicht Punkt Stern, also der Ausdruck für eine beliebige Zeichenfolge. Das ist unsere Überschrift, die wir gern übernehmen wollen. Also wird davor und dahinter eine Markierung gemacht.

\\section{\(.*\)}

Nun wird das Ganze in den Ersetzungsbefehl von vi eingesetzt. Der komplette Aufruf lautet also:

:1,$ s/\\section{\(.*\)}/<H1>\1<\/H1>/g

Der letzte Backslash der Zeile muss sein, sonst glaubt vi, dass der Schrägstrich des </H1> der Befehl dafür wäre, dass der Ersetzungsbereich hier ende. Die Zeichenfolge \1 in der Ersetzung liefert den in der Markierung gemerkten Wert und befördert die Überschrift in die gewünschte, neue Umklammerung.

Machen Sie sich klar, dass Sie sich mit diesem zugegeben etwas kryptischen Befehl vielleicht stundenlange Arbeit ersparen, wenn Sie in einem langen Dokument die Überschriften austauschen müssen. Und überlegen Sie sich auch, ob Sie so etwas mit einem normalen Editor ohne reguläre Ausdrücke auch könnten.

Der Grund, dass so viele Programme mit regulären Ausdrücken umgehen können, liegt daran, dass UNIX dem Programmierer die Suche nach regulären Ausdrücken aus einer Bibliothek anbietet.

Diese Seite basiert auf Inhalten aus dem Buch Arnold Willemer: Wie werde ich UNIX-Guru
Verlagsrechte bei galileo computing


Homepage (C) Copyright 2002 Arnold Willemer