Der UNIX-Editor vi
aus: Wie werde ich UNIX-Guru
und: UNIX-Das umfassende Handbuch
Willemers Informatik-Ecke
Da unter UNX fast alle Konfigurationen über Textdateien laufen, ist ein guter Editor ein wichtiges Werkzeug. In Zeiten der grafischen Oberflächen wirkt die Bedienung auf manchen Einsteiger etwas archaisch. Der vi existiet nicht nur aus Gewohnheit auf UNIX-Systemen, sondern weil er gerade durch sein ungewöhnliches Konzept auch ungewöhnlich leistungsfähig ist. Zugegebenermaßen erschließen sich die Fähigkeiten nicht auf Anhieb. Der Editor vi ist sehr verbreitet. Man findet ihn nicht nur auf jeder UNIX Maschine, sondern auf diversen anderen Plattformen auch. Neben oder statt des originalen vi werkelt oft ein Clone, der nicht selten einige Erweiterungen erfahren hat. Die bekanntesten Vertreter sind elvis und vim. Der vi hat ein originelles Konzept, dessen Vorteile nicht auf Anhieb erkennbar sind. Es gibt drei Modi, in denen sich das Programm befinden kann: den Kommandomodus, den Eingabemodus und den Befehlsmodus.

Kommandomodus

Nach dem Starten des vi befindet man sich im Kommandomodus. Hier kann man im Text positionieren, suchen und Kommandos zur Textveränderung geben. Durch solche Kommandos gelangt man in den Eingabemodus.

Eingabemodus

Der Eingabemodus ist recht simpel. Man kann Text eingeben und mit der Korrekturtaste (Backspace) die letzten Vertipper innerhalb der aktuellen Zeile korrigieren. Alle anderen Korrekturen und Maßnahmen werden vom Kommandomodus aus erledigt, in den man durch die Taste ESC1) wieder zurückkehrt.

Befehlsmodus

Vom Kommandomodus aus erreicht man durch Eingabe des Doppelpunktes den Befehlsmodus. Der Cursor geht in die unterste Zeile und erwartet einen durch Return abgeschlossenen Befehl. Diese Befehle entsprechen übrigens zum Teil denen des sed. Sie betreffen in erster Linie den Text als Ganzes, beispielsweise das Sichern und Wechseln von Texten.


Kommandomodus (Navigation im Text)
 

zum Eingabemodus:
i, a, cx, R
 

zum Kommandomodus:
ESC
 

zum Befehlsmodus:
:
 

zum Kommandomodus:
ESC
 

Eingabemodus
 

Befehlsmodus
 

Die Abbildung zeigt die Modi des vi im Überblick. Nachdem man den vi gestartet hat, befindet man sich im Kommandomodus, in dem auch durch den Text navigiert wird. Cursorpositionierung, Blättern und Suchen findet hier statt. Mit Kommandos wie i (insert), a (append), cx (Das x steht hier für ein Zeichen, das den Bereich bestimmt, auf den die Änderung wirken soll.) (change) und R (replace) gelangt man an der aktuellen Position in den Eingabemodus. Dort gibt man Text ein. Ist die Eingabe soweit abgeschlossen, kehrt man mit ESC wieder zurück in den Kommandomodus, um zur nächsten Stelle zu navigieren. Vom Kommandomodus gelangt man mit dem Doppelpunkt in den Befehlsmodus. Hier gibt man unter anderem die Befehle zum Verlassen, zum Sichern und Hinzuladen.

Verlassen

Das wichtigste zuerst: man kommt aus vi heraus, indem man zunächst ggf. den Editiermodus verlässt. Das geschieht durch ESC. Falls ein ESC zuviel gedrückt wurde, piept vi. Aber das stört eigentlich nur die Akustik.

:q

Dann wechselt man mit dem Doppelpunkt in den Befehlsmodus. Der Cursor geht in die letzte Zeile. Als Befehl gibt man ein einfaches, kleines q (quit) ein und bestätigt mit der Returntaste. Sollte vi nörgeln, dass Änderungen noch nicht gesichert sind, kann man dies mit :q! ignorieren oder mit :wq (write quit) vor dem Verlassen sichern.

Befehl Wirkung
ESC :q verlassen von vi
ESC :q! verlassen von vi und verwerfen aller Änderungen
ESC :wq verlassen von vi und vorheriges Sichern unter dem bisherigen Namen

Starten des vi

Die Arbeitsdatei beim Start nennen

Wollen Sie eine Datei erstellen, geben Sie vi gefolgt von dem Namen der neuen Datei an. Sie landen in einem Bildschirm, auf dem alle Zeilen mit einer Tilde beginnnen. Am Ende des Bildschirms steht der Name der Datei und die Position. Das Tildezeichen soll anzeigen, dass das Ende des Textes erreicht ist. Um etwas einzugeben, tippen Sie ein kleines i (insert). Sie sehen an der Statuszeile, dass vi in den Einfügemodus gewechselt hat. Sie können nun Text von einigen Zeilen eingeben, Tippfehler sollten Sie zunächst ignorieren. Ist der Text eingegeben, erreichen Sie mit ESC wieder in den Kommandomodus. Nun sollten Sie den Text sichern, indem Sie mit einem Doppelpunkt in den Befehlsmodus wechseln. Geben Sie w (write) ein und der Text wird gesichert. Als Dateiname wird derjenige verwandt, den Sie beim Start von vi angaben. Man kann nun vi wieder mit :q verlassen.

Grundlegende Navigation

Sie können die Datei wieder bearbeiten, indem Sie den vi wieder mit dem Dateinamen starten. Nun sehen Sie den Text im Überblick und befinden sich wieder im Kommandomodus. Zunächst bewegen Sie sich an die Stelle, wo Sie etwas ändern wollen. Mit + und - können Sie zeilenweise auf und ab gehen. Mit Leertaste und Backspace können Sie nach links und rechts in der Zeile über den Text fahren. Auf vielen Systemen arbeiten auch die Cursortasten. Haben Sie die Zielstelle erreicht, können Sie wieder mit i neuen Text hinzufügen oder mit kleinem x (wie extract oder wie eine kleine Schere) einzelne Zeichen unter dem Cursor löschen. Zwei Zeilen kann man mit einem großen J (join) zusammenfügen. Mit diesen Kommandos kommt man bereits sicher durch den vi, auch wenn das noch nicht sehr komfortabel ist.

Bewegungen durch den Text im Kommandomodus

Auf den meisten Systemen funktionieren die Standardtasten für die Cursorbewegungen. Das wird den meisten Anwendern am einfachsten erscheinen. Leider ist funktioniert das im Allgemeinen nur auf dem lokalen Rechner. Sobald man mit Hilfe des Netzes auf fernen Rechnern arbeitet (siehe telnet), hat man es mit Terminalemulationen zu tun, bei denen oft die Funktionstasten nicht mehr funktionieren. In solchen Fällen arbeiten aber immer noch die normalen Tasten und die ctrl-Kombinationen. Insofern ist es hilfreich, dass vi auch mit diesen Tasten bedienbar ist.

Weite zurück vor
Ein Zeichen h oder Backspace Leertaste
Ein Wort b w
Zeilenanfang/-ende ^ $
an die n-te Spaltenposition n|
Zeile - +
Seite ctrl-F ctrl-B
zur Zeile n nG
Textanfang/-ende 1G G

Suchen im Text

Suchen: /

vi sucht mit dem Schrägstrich. Daraufhin geht der Cursor in die unterste Zeile und man gibt den Suchbegriff ein und bestätigt mit Return. Um das nächste Erscheinen des gleichen Begriffs zu suchen, gibt man ein kleines n ein. Mit einem großen N kommt man zum vorherliegenden Erscheinen des Begriffs. Will man von vornherein rückwärts suchen, verwendet man das Fragezeichen statt dem Schrägstrich als Befehl. Auch hier arbeiten n und N, allerdings jetzt in der anderen Richtung.

Editieren

Um den Text zu bearbeiten, wird man zunächst Text einfügen. Dazu gibt es aus folgende Kommandos:

Taste Wirkung
i einfügen (engl. insert) an der Cursorstelle
I einfügen vor dem ersten Wort der Zeile
a hinter der Cursorstelle einfügen (engl. append)
A an das Ende der Zeile anhängen

Die Eingaben werden durch ESC bestätigt. Man kann statt dem Einfügen auch existierenden Text ersetzen. Dabei dient das c als Zeichen für Change. Es folgt ein Zeichen, was man ersetzen will. Hier heißt w Wort, $ bis Zeilenende, l ein Zeichen oder die Verdoppelung des c für die ganze Zeile. Auf dem Bildschirm wird der Ausschnitt, den man ersetzt, durch ein Dollarzeichen begrenzt.

Tasten Wirkungsbereich
cw Wort
c$ bis Ende der Zeile
cc aktuelle Zeile
cl Zeichen
r Ersetzt ein Zeichen durch genau ein anderes
R geht in den Überschreibmodus bis zum ESC

Mehrfache Ausführung

Durch das Voranstellen von Zahlen lassen sich diese Befehle vervielfältigen. So ersetzt beispielsweise 5cw die nächsten 5 Worte durch das, was man bis zum ESC eingibt. Durch Eingabe eines Punktes ist dies an anderer Stelle wiederholbar.

Löschen und Kopieren

Das Kommando zum Löschen von Textteilen beginnt mit d (für engl. delete). Wie beim Ändern wird die Weite des Löschens durch den zweiten Buchstaben bestimmt, dabei gilt w für ein Wort, $ bis zum Ende der Zeile und die Verdoppelung des Kommandobuchstaben betrifft die komplette Zeile. Für den Buchstaben wird das l verwendet, aber es gibt auch hier einen extra Buchstaben.

Tasten Wirkungsbereich
dw Wort
d$ bis Ende der Zeile
dd aktuelle Zeile
dl oder x Zeichen

Löschen bis Suchkriterium

Man kann durch Verwendung der Suchfunktion das Ziel angeben, bis wohin gelöscht werden soll. Start ist die aktuelle Cursorposition. Beispiel: d/abc Returntaste löscht alles zwischen hier und dem nächsten Auftreten der Zeichenkette abc.

Der Puffer

Die gelöschten Textbereiche werden in einem Puffer zwischengelagert. Dieser Puffer kann jederzeit an jeder Stelle mit p oder P wieder hervorgebracht werden. Dabei ist p hinter und P an der aktuellen Cursorposition Man kann den Puffer allerdings auch füllen, ohne das Original zu löschen. Man verwendet lediglich das Kommando y (yank) statt d.

Tasten Wirkungsbereich
yw Wort
y$ bis Ende der Zeile
yy aktuelle Zeile

Zeilenvorschub löschen

J vereinigt Zeilen.

Um zwei Zeilen aneinander zu hängen, also den Zeilenvorschub der oberen Zeile zu löschen, geht man in die obere Zeile und gibt ein großes J ein. Die beiden Zeilen werden vereinigt und dazwischen steht ein Leerzeichen.

Geklammerte Bereiche

% als Bereich zwischen Klammern

Für Programmierer besonders interessant ist der Umgang mit Klammern. Man positioniert den Cursor auf einer Klammer und vi springt durch das %-Zeichen auf die korrespondierende Klammer. Dabei werden runde, eckige und geschweifte Klammern akzeptiert. Das Prozentzeichen kann man auch als Bereichsangabe anderer Befehle verwenden. Die Tastenkombination d% löscht den Bereich von der aktuellen Klammer unter dem Cursor bis zum korrespondierenden Klammer.

Einrücken

Besonders interessant ist das Einrücken in Verbindung mit Klammerungen für C-Programmierer. Man kann sich auf eine geschweifte Klammer stellen und durch das Kommando >% den kompletten Block um so viele Leerzeichen einrücken, wie in der Variablen shiftwidth definiert ist.

Tasten Wirkung
% springe von dieser Klammer zur korrespondierenden Klammer
d% lösche alles zwischen dieser Klammer und der korrespondierenden
c% ersetze alles zwischen dieser Klammer und der korrespondierenden
y% schiebe alles zwischen den Klammern in den Puffer
<% bzw. >% Ein- bzw. Ausrücken des eingeklammerten Bereichs

Mehrfachausführung

Soll ein Kommando mehrfach ausgeführt werden, stellt man einem beliebigen Kommando die Häufigkeit voran. Beispiele:

Kommando Wirkung
4dw löscht die nächsten vier Worte
77i - ESC erzeugt 77 Bindestriche
3cl ersetzt die nächsten 3 Zeichen durch die Eingabe
12yy kopiert die nächsten 12 Zeilen in den Kopierpuffer

Mach's nochmal, vi!

Ein Punkt wiederholt das letzte Kommando

Ein besonderes Feature von vi ist der Punkt. In der Kommandoebene eingegeben wiederholt er das letzte Kommando an der aktuellen Cursorposition. Auch vor dem Punkt kann man die Häufigkeit angeben. Hat man nach 10dd noch 10. getippt, werden 100 Zeilen gelöscht.

Schiefgelaufen

Wenn mal etwas schiefging: Versehentliches Löschen und andere ungewollte Vorgänge kann man mit u (undo) ungeschehen machen. Befindet man sich in einem unbekannten Modus, erreicht man mit ESC die Kommandoebene, von der aus das u eingegeben werden muss.

Undo nicht unbedingt mehrstufig

Stellt man fest, dass nicht der letzte, sondern der vorletzte Befehl den Schaden verursacht hat, der 100 Seiten Manuskript mit der Schredderfunktion bearbeitete, kann man zwei Dinge tun. Das erste ist, dass man u ein weiteres Mal drückt und hofft, eine der neueren Implementationen von vi zu benutzen, die ein Undo in mehreren Stufen erlauben. Es kann aber auch sein, dass statt der mehrstufigen Änderung nur ein Redo erfolgt ist. Dann sollte man aufstehen, tief durchatmen und überlegen, in welchem Zustand sich die Datei auf der Platte befindet und dann mit :q! verlassen, um die letzte Version zu verwenden oder das Thema Zwischenspeichern noch einmal intensiv durchdenken. Ein versierter vi-Benutzer würde an dieser Stelle allerdings den aktuellen Text nicht mit :q! verwerfen, sondern ihn unter einem anderen Namen sichern. Dazu wird :w gefolgt von einem Leerzeichen und dem neuen Dateinamen aufgerufen. Also sichert :w sicher den Text unter dem Namen sicher. Anschließend kann man mit dem Kommando diff ermitteln, welche Unterschiede zwischen sicher und dem letzten Stand bestehen. Sollte statt dessen die verwendete Version ein mehrstufiges Undo beherrschen, stellt sich die Frage, wie man ein Undo zuviel wieder rückgängig machen kann. Hier empfielt sich ein Experiment mit ctrl-R.

Wichtige Befehle des Befehlsmodus

sichern und laden

Der Befehlsmodus wird mit dem Doppelpunkt aktiviert. Die Kommandos q zum Verlassen und w zum Sichern wurden bereits vorgestellt. Auch dass man dem Kommando w als Parameter noch einen Dateinamen mitgeben kann, um den Text unter diesem Namen wegzuschreiben, wurde bereits erwähnt. Als Gegenstück zum w gibt es ein r (read), um Texte in den aktuellen Text hineinzulesen. Auch hier wird der Dateiname als Parameter gegeben. Der angegebene Text erscheint danach an der aktuellen Cursorposition.

Shellaufruf

Mit dem Ausrufezeichen wird die restliche Befehlszeile an eine Shell weitergeleitet. Man kann so aus dem Editor einen Compiler starten oder andere Systemkommandos geben. Probieren Sie einmal :!ls aus!

Befehl Wirkung
:n Wurde vi mit mehreren Dateien aufgerufen, lade die nächste
:r Datei Lade die Datei an der Cursorposition hinzu
:d Lösche Zeile
:! Kommando Es wird eine Shell gestartet, um das Kommando abzusetzen

Befehle beginnen mit dem Zeilenbereich

Für viele Kommandos der Befehlszeile kann ein Bereich von Zeilen vorangestellt werden, auf denen sie wirken sollen. So bewirkt das Voranstellen einer 8 vor w datei, dass Zeile 8 unter dem Namen datei gespeichert wird. Einen Bereich von Zeilen gibt man durch die erste Zeilennummer, gefolgt von einem Komma und der Zahl der letzten Zeile an. 12,15 bezeichnet also die Zeilen zwischen 12 und 15. Für bestimmte Zeilen gibt es besondere Symbole. Die aktuelle Zeile, in der sich der Cursor befindet, wird durch einen Punkt bezeichnet. Das Dollarzeichen bezeichnet die letzte Zeile. Innerhalb der Bereichsangabe darf kein Leerzeichen stehen.

Angabe Bereich
25 die Zeile 25
5,25 der Bereich von Zeile 5 bis 25
.,25 der Bereich von der aktuellen Zeile bis Zeile 25
25,$ von Zeile 25 bis Dateiende
.,$ von aktueller Zeile bis Dateiende

Ersetzen

Zum Ersetzen einer Zeichenfolge durch eine andere muss man zunächst durch Doppelpunkt in den Befehlsmodus wechseln. Der folgende Befehl bewirkt das Ersetzen der Zeichenkette >>suchmuster<< durch die Zeichenkette >>ersetze<< im gesamten Text.2)

:1,$ s/suchmuster/ersetze/g

Dieser Befehl sollte zunächst am Leerzeichen in zwei Teile zerlegt werden. Der Bereich, in dem der Befehl wirkt, wird gleich zu Anfang der Zeile angegeben. Steht dort nichts wird nur die aktuelle Zeile herangezogen. In diesem Fall heißt 1,$ von der ersten bis zur letzten Zeile. Das Dollarzeichen als Symbol für das Ende ist in vi durchgängig. Dann folgt der Befehl s für suchen (engl. search). Das Suchmuster und die Ersetzung müssen voneinander und von den Kommandos vorher und nachher abgetrennt werden. Dazu wird meist der Schrägstrich verwendet. Es könnte auch jedes andere Zeichen sein, das im Suchmuster nicht vorkommt. Am Ende kommt das g (global), damit die Ersetzung nicht beim ersten Mal stehen bleibt. Das Suchmuster ist übrigens ein regulärer Ausdruck, so wie er auch von grep verwendet wird.

Settings

Um Optionen ein oder abzuschalten, geht man zunächst mit dem Doppelpunkt in den Befehlsmodus und gibt dort set, gefolgt von der Option an. Man kann vi durch viele Optionen konfigurieren. Die verschiedenen Implementationen bieten da unterschiedliche Möglichkeiten. Um eine Übersicht zu erhalten, gibt man set all an und blättert sich mit der Leertaste durch die Seiten. Mit ESC kommt man zurück in den Kommandomodus.

Einschalten Ausschalten Wirkung
set all zeigt die aktuellen Settings an
set list set nolist zeigt Sonderzeichen an
set sw n (shiftwidth) setze Einrücklevel auf n Stellen
set ai set noai (autoinsert) Automatisches Einrücken
set nu set nonu (number) Zeilennummern anzeigen
set smd set nosmd (showmode) zeige den Textmodus an
set sm set nosm (showmatch) Anzeige der Gegenklammer bei Eingabe

Steuerung des Zeilenumbruchs

vi bricht die Anzeige am Ende jeder Zeile um. Dieses Verhalten kann in manchen Fällen sehr lästig sein. Durch nowrap schaltet man es ab, mit wrap wieder ein. Bei der Texteingabe wird erst bei Return eine neue Zeile erzeugt. Dieses kann man durch wm (wrapmargin) ändern. Gibt man eine Zahl ungleich 0 an, wird so viele Zeichen vor Erreichen des rechten Rands umgebrochen. Dabei bricht vi immer wortweise um. Er nimmt also das angefangene Wort mit in die neue Zeile und fügt davor ein Zeilenumbruchzeichen (new line) ein.

Literatur

Arnold Robbins, Imke Schenk (Übersetzer): vi- Editor. Kurz und gut. O'Reilly, 2000.
1 Man kann darüber streiten, ob diese Taste als Abschluss der Eingabe eine glückliche Wahl war. Inzwischen verwenden fast alle Programme die ESC-Taste unter der Bedeutung des Verwerfens von Eingaben. Unter vi jedenfalls wird die Eingabe belassen und der Modus verlassen.
2 Dies ist mein Lieblingsbefehl. Nennen Sie diese Folge von Buchstaben mit der Anmerkung "...ist doch eigentlich naheliegend, oder?" und man wird Ihren Namen nur noch in Ehrfurcht aussprechen.

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