orm@doc-tcpip.org | Erstellt: Mai 2001 - Letzte Modifikation: März 2015 |
Ich bin vi-Fan, der vi ist der größte Editor aller Zeiten - mindestens. Ich finde auch nicht, daß er nicht intuitiv sei - völliger Blödsinn. Folgende Aussagen treffen sicher zu: Die Eintrittsschranke liegt sehr hoch, man kann nicht mal eben einen Text editieren. Dafür bietet der vi enormen Leistungsumfang, ist absolut portabel, überall vorhanden und gut zu konfigurieren. Und wer ihn nicht bedienen kann, wirds auch sonst zu nichts bringen.
Hier der Inhalt dieser Seite. Typische Probleme sind hier gesondert
aufgeführt:
Wie mache ich was - allerlei Praktisches
Ansonsten die vi-Referenz:
Das absolute Minimum
Bewegen im Text
Einfügen und Löschen von Text
Suchen im Text
Editieren von Text
Editieren von Textteilen - Bereiche
Öffnen und Speichern von Files
Editieren vieler Files
Kopieren zwischen Files
Mehrere Fenster öffnen
Die Textpuffer
Die Textmarker
Das "mappen" von Tasten, Abkürzungen und das
.exrc File
Das Erstellen von Macros
Die absoluten Minimal-Kenntnisse im Schnelldurchgang:
Ein File zum editieren öffnen bzw. neu anlegen:
vi filename
Dann mit den Pfeiltasten oder den Tasten j, k, h, l die Stelle
suchen, wo man was editieren möchte. Danach kommt man mit der
Taste i in den Modus zum editieren und kann schreiben.
Löschen geht mit ESC x (ein Buchstabe) oder mit
ESC dd (eine
Zeile). ESC D löscht den Rest einer Zeile.
Nach getaner Arbeit kommt man mit ESC : wq aus dem File raus -
es wird dabei gesichert. Hat man was versaubeutelt, dann kann man
mit ESC : q! das File ohne Sichern verlassen.
Viele Dinge lassen sich am Doppelpunkt für die aktuelle Session einstellen. Sollen solche Setzungen beim Starten da sein, so muss man sie ins rc File eintragen.
:set - zeigt alle Werte, die sich vom Default unterscheiden :set all - zeigt alle Werte :set foo? - zeigt den Wert von foo :set foo& - auf den Default-Wert setzen :setlocal foo - nur für diese Session :verbose set foo? - wo wurde foo zuletzt gesetzt? Automatisch Einrücken: :set tabstop=4 - ein Tab wird 4 Stellen lang :set expandtab - es wird aber nicht das Tab Zeichen (<09>) benutzt :set shiftwidth=4 - Einrücken ist 4 Stellen :set autoindent - Anschalten :set smartindent - Achtet auf den code :set pastetoggle=- im .vimrc - beim pasten wird nicht eingerückt :set paste - wie oben im Editor ctrl-t, ctrl-d - rückt die aktuelle Zeile ein/aus Syntax higligthing anschalten: :syntax on/off Bestimmte File Extensionen einem Syntax Typ zuordnen: Lokal file anlegen: ~/.vim/filetype.vim Mit dem Inhalt: " SQL ist das Format unserer osp files au BufNewFile,BufRead *.osp setf sql Und alle *.osp werden als SQL Code erkannt. Globales File liegt hier: /usr/share/vim/vim74/ Suchen case insensitiv: /blabl\c oder :set ignorecase (set ic) später :set noic Wenn man ignorecase per standard setzt, kann man umgekehrt den Case erzwingen mit \C. Es gibt auch noch smartcase, da wird case insensitive gesucht, wenn Gross und Klein gemischt im Key vorkommen.
Wo bin ich im Moment? CTRL-G zeigt das aktuelle File, die aktuelle Zeile
sowie die aktuelle Spalte. Und als Goodie noch den Ort in Prozent
bezogen auf das ganze File sowie die Gesamtanzahl der Zeilen.
Alle Befehle können mit einem Zähler abgesetzt werden:
4b springt an den Anfang des 5. folgenden Wortes.
h Ein Zeichen nach Links
l Ein Zeichen nach Rechts
w Ein Wort nach Rechts
b Ein Wort nach Links
W springt an den Anfang des nächsten Wortes
B springt an den Anfang des Wortes
e springt an das Ende des Wortes
E springt an das Ende des nächsten Wortes
k Eine Zeile nach oben (geht auch -)
j Eine Zeile nach unten (geht auch +)
0 An den Zeilenanfang
$ An das Zeilenende - 5$ Ende Zeile 5
von aktueller Zeile
^,_ Zum ersten Wort ohne Leerzeichen davor (Beginn der Zeile/Spalte)
+,- Eine zeile vor bzw. zurück.
G an das Textende
1G an den Textanfang
[x]I springt in die x-te Spalte.
Auch hier kann man wieder mit Zählern arbeiten:
10G springt in die 10. Zeile des Textes.
10j springt 10 Zeilen vorraus.
10H springt 10 Zeilen unter den Seitenanfang.
CTRL B springt einen Bildschirminhalt zurück
CTRL F springt einen Bildschirminhalt voraus
CTRL D springt einen halben Bildschirminhalt zurück
CTRL U springt einen halben Bildschirminhalt voraus
Sehr praktisch ist auch folgendes Kommando:
z RETURN bringt die Zeile mit dem Cursor an den oberen Rand des Bildschirmes
z- bringt die Zeile mit dem Cursor an den unteren Rand des Bildschirmes
z. bringt die Zeile mit dem Cursor in die Mitte des Bildschirmes
i Einfügen vor Cursor
a Einfügen nach Cursor
I Einfügen am Zeilenstart
A Einfügen am Zeilenende
p Pasten in der nächsten Zeile
P Pasten am Cursor
r Ein Zeichen ersetzen
5rU Fünf Zeichen mit U ersetzen
R Überschreiben
cw Ein Wort ersetzen
C,c$ Ändern bis zum Ende der Zeile
dh Löschen von einem Zeichen zurück (links)
dl Löschen von einem Zeichen vorraus (rechts)
db Löschen von einem Wort zurück (links)
dw Löschen von einem Wort vorraus (rechts)
dB Löschen von einem "nonblanc" Wort zurück (links)
dW Löschen von einem "nonblanc" Wort vorraus (rechts)
d$ Löschen bis zum Zeilenende
d0,d^ Löschen bis zum Zeilenanfang
dL Löschen des Bildschirminhaltes
dG Löschen bis zum File-Ende
de Löschen bis zum Wort-Ende
Mit c statt d: dann kommt man direkt im den Edit Modus
Die meisten Kommandos haben noch eine andere Form:
x ist dl
X ist dh
D ist d$
dd ist 0d$
C ist c$
cc ist0c$
Jedes der genannten Kommandos kann man wiederholt ausführen, indem
man die Punkt (.) Taste drückt. Außerdem kann man natürlich auch
Bereiche im Text angeben:
ESC 10yy kopiert die aktuelle Zeile und 9 weitere in den Speicher
ESC 10dd löscht dieselben Zeilen nach dem Erstellen der Kopie
Es ist auch möglich, bis zu einem bestimmen String zu löschen:
d/string löscht bis string gefunden wird.
Oder eine bestimmt Anzahl von Zeilen löschen:
dZahlj löscht Zahl Zeilen nach unten
(wegen des j)
d5G löscht 5 Zeilen nach unten,
Start in der aktuellen Zeile (Cursor)
Setzt man diese Befehle ab, so wird vom Cursor bis zum ersten Buchstaben
des Such-Strings gelöscht (das ist der vi-mode). Mit den folgenden Befehlen
geht das auch alles, aber im ex-Mode - daher wird immer von Zeile zu
Zeile gelöscht.
:1,/^[ ]*$/d löscht bis zur ersten leeren Zeile.
:1,/Seppel/d löscht alle Zeilen bis zur Zeile mit "Seppel".
:/Seppel/d löscht die nächste Zeile, in der "Seppel" vorkommt.
Das kann man "globalisieren":
:g/Seppel/d löscht alle Zeilen, in der "Seppel" vorkommt.
Die Logik kann man auch umdrehen:
:v/Seppel/d löscht alle Zeilen, in der "Seppel" nicht vorkommt.
:/Seppel/+2d löscht die zwei Zeilen, die auf die Zeile mit "Seppel" folgen.
:/Seppel/,/Kasperl/d löscht ab der Zeile mit "Seppel" bis zur Zeile mit "Kasperl".
:.,/Seppel/m456 löscht von hier (der Punkt) bis zur Zeile mit "Seppel" und fügt das Ganze nach Zeile 456 wieder ein.
:1,/^[ ]/d löscht bis zur ersten Zeile, die mit 4 Leerzeichen beginnt.
Wer aufgepasst hat, der hat jetzt verstanden, wie es geht: Man gibt immer einen Bereich an (Strings, Variablen oder Zahlen, auch gemischt, durch ein Komma getrennt) und eine Aktion (Löschen, Kopieren ...).
Hier eine kleine Liste der Regular Expressions, die der vi kennt.
. jedes Einzelzeichen (keine neue Zeile) * jede Anzahl des vorstehenden Zeichen ^ folgendes Zeichen, wenn am Beginn einer Zeile $ vorhergehendes Zeichen, wenn am Ende einer Zeile [ ] Zeichenklasse: alles, was in den Klammern steht [^] Zeichenklasse: alles, was nicht in den Klammern steht \( \) String speichern für spätere Benutzung \< folgende Zeichen, wenn am Anfang eines Wortes \> folgende Zeichen, wenn am Ende eines Wortes \ Escape Zeichen, um die Sonderfunktion aufzuheben \n n=Nummer, wiederholt vorherige Eingabe n-mal & vorherige Suche wiederholen ~ vorherige Ersetzung wiederholen \u Umwandlung in Großbuchstaben (ein Zeichen) \U Umwandlung in Großbuchstaben (mehrere Zeichen) \l Umwandlung in Kleinbuchstaben (ein Zeichen) \L Umwandlung in Kleinbuchstaben (mehrere Zeichen) \e Schaltet \u und \l aus. \E Schaltet \U und \L aus.
Gross- und Kleinschreibung ~ am Cursor Case toggeln 3~ 3 Zeichen toggeln g~iw im aktuellen Wort toggeln g~~ / V~~ Zeile toggeln g~3w drei Worte toggeln g~$ bis Ende der Zeile toggeln Das alles geht auch mit U und u statt ~ : gUU / guu ==> Gross / Klein schreiben Oder: %s/.*/\L&/ (\U) ==> Gross / Klein schreiben tr '[:upper:]''[:lower:]'
fx nach rechts bis x gefunden ist
Fx nach links bis x gefunden ist
tx nach rechts bis x gefunden ist, Cursor auf die Stelle davor
Tx nach links bis x gefunden ist, Cursor auf die Stelle davor
/string Suche String nach unten
?string Suche String nach oben
n nächster Treffer in die eingestellte Richtung.
N nächster Treffer in die andere Richtung.
/^string\> findet die Zeile, die mit String beginnt.
/^string$ findet die Zeile, in der nur
string steht.
/^$ findet leere Zeilen.
/^..*$ findet die Zeilen mit mindestens einem
Zeichen.
/^.....$ findet die Zeilen mit genau fünf
Zeichen.
/^\. findet die Zeilen, die mit einem Punkt
beginnen.
/^[^\.] findet die Zeilen, die nicht mit einem Punkt
beginnen.
/^\.[A-Z0-9] findet die Zeilen, die mit einem
Punkt, gefolgt von Großbuchstabe oder Zahl beginnen.
/[Ss]tring findet String und string.
/[Ss][gG] findet Sg, sg, SG
und sG.
/[A-Z][A-Z]* findet einen oder mehr
Großbuchstaben.
/Str[aeiou]ng findet Strang, Streng etc..
/Str[^aeiou]ng findet alle Strings ohne Vokal.
/Str.ng findet alle Strings - für den Punkt
kann jedes Zeichen stehen.
Hier gibt es auch wieder einen weiteren Modus mit den ex-Kommandos. Das
Such-Kommando lautet hier g
Ich will einen Buchstabenlöschen und rechts neben dem Nächsten wieder einfügen:
xp tauscht zwei Buchstaben
Xp tauscht zwei Buchstaben, aber anders herum
Dabei kann ich mich mit h, l sowie j, k im Text bewegen.
Ich kann auch Zeilen tauschen. Dabei kann ich mich auch im Text bewegen:
ddp Tauscht zwei Zeilen, die Gelöschte wird nach der Folgenden
eingefügt.
ddkp Tauscht zwei Zeilen, die Gelöschte wird vor die darüberstehende Zeile kopiert. Mit mehr "k" springe ich mher Zeilen nach oben (mit "j"
nach unten).
Vertauschen von Worten:
wort1:wort2 wort1:wort2Das erste mit dem zweiten Wort tauschen:
wort2:wort1 wort2:wort1Man kann dabei den ":" ersetzen, oder Sachen Einfügen im Ausdruck rechts:
Ich habe wort2 mit wort1 getauscht.. Ich habe wort2 mit wort1 getauscht..Dabei muss man beachten:
:%s/\<./\u&/gerster Buchstabe aller Wörter werden zu Großbuchstaben.
>>fügt einen Tabulator ein,
<<entfernt ihn wieder.
:% heißt, das Kommando soll für den ganzen Text gelten
:1,. heißt, das Kommando gilt von Zeile 1 bis zur aktuellen Zeile
:.,$ von der aktuellen Zeile bis zum Ende des Textes
:14,45 von der Zeile 14 bis zur Zeile 45
:14;45 von der Zeile 14 bis zur Zeile 45.
Die aktuelle Zeile wird auf die Zeile 14 gesetzt
:.,+4 von der aktuellen Zeile 4 Zeilen weiter
:n von der aktuellen in Zeile n
:'a in die mit a markierte Zeile
:a+4,a-4 4 Zeilen vor und nach der mit a
markierten Zeile
Das aktuell bearbeitet File kann man umbenennen:
:f Name benennt das File nach Name um. Das Original-File
bleibt erhalten.
Will man einen Teil des aktuellen Files in ein anderes File speichern, so
kann man folgendes tun:
:10,100w >> Name speichert die Zeilen 10 bis 100 in das File
Name
Mit % kann man eine Kopie des aktuellen Standes eines Files
machen:
:w %.kopie
(Also: mein_file wird als mein_file.kopie gespeichert..)
Es ist möglich, ein File an bestimmten Stellen zu öffnen:
Ein File an einer bestimmten Linie öffnen:
vi +n filename öffnet das File filename auf der
Linie n.
Oder es wird nach einem bestimmten String gesucht:
vi +/string filename öffnet das File filename an der
Linie, in der der String string steht.
.
Hat man ein File dadurch zerschoßen, das man den vi gekillt hat
(Maschinencrash z.B.) dann kann man das letzte File meist aus dem
temporären File wieder herstellen.
Dazu gibt es den Schalter -r. Man ruft den vi also so
auf:
vi -r der vi zeigt jetzt alle temporären Files an.
vi -r filename nimmt als Input das letzte
temporäre File, das zum File "filename" gehört. Das kann man dann
prüfen und neu abspeichern.
Oft hat man ein Problem mit großen Files. Es kommt beim
Öffnen eine Meldung, das der Speicherplatz nicht ausreicht.
Der VI legt beim Öffnen das File als Kopie in den Speicher, und
arbeitet auf dieser Kopie. Erst beim Schließen wird das File
wieder Syncronisiert. Ist im entsprechenden Verzeichnis nicht
genug Platz, so kommt es zu dieser Meldung. Mit
: set dir sieht man das aktuelle Verzeichnis, in
das der VI das temporäre File legt. Mit
: set dir=/neues/verzeichnis kann man ein anderes
Verzeichnis setzen. Das kann man im File exrc festlegen
oder beim Aufruf per
vi -c "set dir=/neues/verzeichnis"
Man kann beliebig viele Files im Zugriff haben. Das geht einfach
mit dem Aufruf vi xx vvv yyy oder sogar mit vi * wenn
man weiß, was man tut.
Folgende Befehle sind in diesem Fall wichtig:
:n springt in das nächste File, warnt wenn das aktuelle nicht gesichert wurde.
CTRL g zeigt den Namen des Files, das momentan in Arbeit ist.
:f dasselbe, zusätzlich kann man bei Angabe eines Namens das File umbenennen.
:args zeigt die Files, die editiert werden - das aktuelle File ist hervorgehoben.
Man kann aus einem File noch ein anderes editieren:
Man sichert mit :w und kann mit :e
xxxx das andere File
öffnen.
Mit den Zeichen # und % springt man zwischen den Files.
% ist das aktuelle File, # das alternative (e# ist immer "das
andere File").
Mit % kann man zb. eine Kopie des aktuellen Standes eines Files
machen:
:w %.kopie
(Also: mein_file wird als mein_file.kopie gespeichert..)
Das macht man einfach mit Hilfe der "named buffers". Diese werden
beim Wechsel von einem File ins andere (egal ob man das File neu
öffnet oder schon beim Aufruf des vi angegeben hat - es muß nur
dieselbe vi-Session sein) nicht gelöscht.
Man schneidet was aus, legt es in den Named Buffer und öffnet ein
anderes File. Hier ein kleines Beispiel:
"a8yy legt die folgenden 8 Zeilen in den Buffer
a.
("A8yy würde die folgenden 8 Zeilen an den Buffer
a anhängen -
der Buffer wird geleert, wenn man ihn wieder als a anspricht)
Im neuen File legt man die 8 Zeilen wieder hin:
"ap
Ich möchte...
... Teile eines Files in ein anderes kopieren!
... verschiedene Textstücke in einen Speicher kopieren!
... bis zu einem bestimmten Wort löschen!
... für die folgenden 32 Zeilen einen Tabulator einfügen!
... alle Tabulatoren, End of Line etc. sehen!
... etwas, was ich vor 5 Minuten gelöscht habe wiederholen!
... nach einem unfreiwilligen Ausstieg mein modifiziertes File wiederhaben!
... den VI nur für HTML-Text (oder sonst was) nutzen!
... zwei Files zugleich editieren!
... 100 gleiche Zeilen schreiben, in denen sich nur 1 Wort ändert!
... alle leeren Zeilen löschen!
... etwas nehmen und es bei Zeile xx wieder einfügen!
... ein File an einer bestimmten Stelle öffnen!
... lange Linien in einem File auf 80 Zeichen
umbrechen!
... eine lange Namensliste sortieren!
... ein riesiges File öffnen!
Das ist ein Feature was meiner Erfahrung nach sehr stark von der Implementation des vi abhängt - es kann also sein, das einige oder alle der folgenden Kommandos nicht funktionieren. Dann hat man halt Pech gehabt.
Man kann einmal den vi mit dem Schalter -o aufrufen. So öffnet vi -o file1 file2 file3 jedes File in einem eigenen Fenster. Der Bildschirm wird dabei horizontal geteilt, mit vi -O wird der Bildschirm vertikal geteilt. Mit vi -o N kann man N Fenster öffnen.
In einige vi's geht es mit CTRL W S. Sollte dann der Bildschirm eingefroren sein, dann kommt man mit CTRL Q wieder ans Arbeiten.
Zum Schluß gibt es noch das split-Kommando: mit :N split (wobei N die Höhe des Fensters angibt) kann man das aktuelle Fenster in zwei teilen. Vertikal geht das auch: :N vsplit. Will man während man ein File bearbeitet, ein anderes öffnen, dann braucht man die Kommandos new und vnew: :N new file1. Es geht auch im Read-only Modus: sview. Um die offenen Fenster zu wechseln, schließen oder auszublenden dienen die Befehle quit, close, hide und only.
Man wechselt zwischen den Fenstern mit CTRL-W w. Mit h, j, k, l wechselt man in die umliegenden Fenster. Mit t und b kann man sich nach oben oder nach unten im aktuellen Fenster bewegen.
Die gleichen Kommandos in Grossbuchstaben ermöglichen es, Fenster zu verschieben.
Mehrere Fenster kann man mit Kommandos parallel bedienen, mit all. So schliesst :qall alle Fenster, :wall schreibt alle Fenster etc.
Es gibt im vi genau 36 Textpuffer, die der User nutzen kann. Man unterscheidet zwischen statischen Puffern, von denen 26 möglich sind, und dynamischen Puffern, von denen es 10 gibt. Die Puffer des vi haben eine spezielle Eigenschaft: man kann einen Befehl ausschreiben, ihn in einen Puffer kopieren, und dann den Puffer mit dem Klammeraffen ("@") aufrufen - der Befehl wird ausgeführt. Das ist eigentlich nicht von praktischen Nutzen, jedoch gut zu wissen.
Diese Puffer werden mit den Buchstaben des Alphabeths benannt und ändern sich nur, wenn der User sie explizit anspricht. Es macht einen Unterschied, ob man den Puffer mit großen oder kleinen Buchstaben benennt: benutzt man Großbuchstaben, so wird der Text an den Inhalt des Puffers angefügt. Mit Kleinbuchstaben wird der Puffer neu überschrieben.
In diese Puffer schreibt der vi gelöschte Zeilen oder Zeichen.
Die Puffer werden mit den Zahlen 1 - 9 benannt. Löscht man
etwas, so wird das in den ersten Puffer (der Puffer "0")
gelegt. Bei weiterem Löschen wandert der Inhalt in der
Hierarchie der Puffer weiter hoch. Wirklich gelöscht ist es
erst, wenn der Puffer 9 überschrieben wird.
Je nachdem, wie viel man löscht, kann man die Information solange
wieder aus dem Puffer holen, bis sie im hypothetischen Puffer 10
angekommen ist... (das gilt nur für ganze Zeilen).
Das Laden geschieht mit den Anführungsstrichen ("). Ein
Ladekommando setzt sich immer zusammen aus dem Namen des Puffers
und einem Bewegungskommando (delete, yank).
Hier eine Reihe Beispiele:
"a5yy kopiert die fünf folgenden Zeilen in den Puffer a.
"A3yy hängt an den Puffer a weitere 3 Zeilen an.
"fy'd kopiert von Cursor bis zur Textmarke d alles in den Puffer f.
Mit so einem Befehl kopiert man immer bis zur Textmarke, die Marke
selbst also nicht mehr.
Möchte man die nummerierten Buffer durchsuchen, so geht man folgenderart
vor:
Zuerst ruft man den Buffer 1 auf
"1p
Die entsprechende Zeile wird eingefügt. War es das nicht, so
entfernt man die Zeile mit
u und wieder holt mit dem ..
Das wird wiederholt, bis die Buffer alle geprüft sind - dann ist der
String verloren...
Einzelne Buchstaben oder Wörter werden erst garnicht in die
nummerierten Buffer gelegt.
Zum Einfügen werden auch die Anführungsstriche (") benutzt. Im Kommando wird jetzt statt des Bewegungskommandos das Pastekommando (p oder P) gegeben. Das kleine p fügt den Pufferinhalt nach dem Cursor ein, das große P fügt vor dem Cursor ein.
Der vi verfügt über 26 Textmarker, die durch die Buchstaben des
Alphabets benannt werden. Ein Marker wird mit dem Befehl
"m"
und der Angabe des Namens gesetzt. Der gewählte Punkt ist dann
die Referenz für Bewegungen, Löschen, Kopieren etc.
Beispiele:
ma setzt den Marker a.
Auf diesen kann man sich jetzt bei der Bewegung beziehen:
`a (Akzent) springt genau auf die Marke,
'a (Hochkomma) an den Anfang
der Zeile der Marke.
Damit kann man ganze Textblöcke löschen oder Verschieben, z.B. zu Beginn
des Bereiches mit mq einen Marker setzen, an das Ende
des Bereiches laufen und den Textblock ausschneiden oder kopieren:
y'q bzw. d'q. Das ist dann im Puffer, und
man kann es an beliebiger Stelle wieder Einfügen.
Abkürzungen sind sehr einfach und praktisch. Ich will z.B.
nicht immer "Dynamic Host Configuration Protocol" ausschreiben.
Also setze ich folgenden Befehl ab:
:abbr dhcp Dynamic Host Configuration Protocol
Wenn ich jetzt "dhcp" (mit Leerzeichen davor und dahinter) tippe,
dann expandiert der vi das sofort zum langen Wort. Möchte ich
jetzt einmal doch nur die 4 Buchstaben "dhcp" schreiben, dann
kann ich entweder "dhcp^V" tippen (also d,h,c,p,CTRL-V,
Leertaste) oder ich kann mit dem Kommando "unabbr" die
Abkürzung zurücksetzen.
Es ist wichtig, sich zu merken, daß bei Abkürzungen der vi auf
das Zeichen nach der eingebenen Sequenz wartet.
Hierbei wird die definierte Sequenz sofort expandiert, und
man kann auch komplizierte Macros auf eine Tastenkombination
binden. Dazu dient das Kommando "map".
Es gibt zwei Möglichkeiten, die verschiedene Modi des
vi benutzten.
map funktioniert mit Kommandosequenzen, die im
Kommando Mode (also nach einem ESCAPE) eingegeben werden,
während map! auf im Textmodus getippte
Sequenzen reagiert.
Die Eingabe des folgenden Befehls bringt den vi dazu,
die Folge "dhcp" nicht mehr auf den Bildschirm zu bringen,
sondern direkt zu ersetzen:
:map! dhcp Dynamic Host Configuration Protocol
Der "map!"-Befehl kann wie gehabt mit "unmap!" wieder aufgehoben
werden und mit CTRL-V temporär umgangen werden. Man kann alle
aktuellen Mappings durch eingeben von "map!" am Doppelpunkt sehen.
Wie im vorigen Abschnitt, nur das die definierte Sequenz im Kommando-Mode, also nach einem ESCAPE, benutzt werden muß. Der "map"-Befehl kann wie gehabt mit "unmap" wieder aufgehoben werden und mit CTRL-V temporär umgangen werden. Man kann alle aktuellen Mappings durch eingeben von "map" am Doppelpunkt sehen.
Abkürzungen und Mappings kann man dem VI beim starten
mitgeben. Es ist auch möglich, eine ganze Reihe anderer
Steuerbefehle mitzugeben - und man kann pro Unterverzeichnis
ein spezielles .exrc pflegen (z.B. für HTML und LaTex).
So kann man verschiedene, spezialisierte VI-Instanzen laufen
lassen. Über die Umgebungsvariable EXINIT kann bestimmt werden, wie der
VI starten soll. Es ist auch jederzeit möglich, ein vorhandenes .exrc
einzulesen:
:so .xxxx
Hier ein Beispiel .exrc:
" Ein Kommentar set noautoindent set showmode set tabstop=8 ... ab c < CENTER> ab _c < /CENTER> ab hf < A HREF=" ab _h < /A> ... " Ein Macro: " CTRL X Nummer: H1 bis H2 (1-2) map ^X1 I< H1>^A< /H1> ^[D^[o map ^X2 I< H2>^A< /H2> ^[D^[o ...Die Syntax ist eigentlich selbsterklärend, und zu den Macros kommen wir jetzt.
Das schreiben von Macros ist eigentlich sehr einfach, da es sich um Abfolgen von vi-Befehlen handelt, die man normalerweise auch so Absetzen kann. Aufgrund der Struktur der Buffer ist es innerhalb eines Macros zusätzlich möglich, Dinge zeitlich zu versetzen, also eine Eingabe zu machen, die erst nach der Eingabe an die richtige Stelle kopiert wird.
Die große Gefahr sind recursive macros, also Macros, die sich selbst während ihrer Ausführung erneut aufrufen. Ein Beispiel wäre folgendes Mapping: map! dhcp Das dhcp klasse sein. Hier ruft das Macro sich selbst auf und es kommt zur Katatrophe. Daher ist man gut beraten, wenn man sich seine Macros vorher gut anschaut und gründlich testet, bevor man sie eingibt oder im .exrc verewigt.
Hier einige nützliche Beispiele - der Fantasie sind keine
Grenzen gesetzt. In den Macros müssen eine Reihe Steuersequenzen
eingesetzt werden. Diese werden mit der CTRL-Taste (STRG-Taste)
erzeugt. So ist ^X die Kombination CTRL-X etc. Ein spezieller
Fall ist die Escape-Sequenz ^[, die man mit der Kombination
CTRL-V und dann ESCAPE-Taste erhält. Da es Stuerzeichen sind,
ist es nicht möglich, eine solche Zeile z.B. mit der Maus
zu kopieren (greppen), da die Steuerzeichen verloren gehen.
map ^X1 I< H1>^A< /H1> ^[D^[o
Hier ist definiert, das die Tastenkombination CTRL-X auf einer
gerade geschriebenen Zeile folgende Aktionen auslöst:
Es wird am Anfang der Zeile die Header-1 Anweisung eingefügt,
am Ende ausgeführt, bis zum Zeilenende gelöscht und eine neue
Zeile zur Eingabe geöffnet.
map ^X^L o< /A>^[kO">^[I< A HREF="http://
Die Kombination CTRL-x + w führt dazu, das der unter dem
Cursor liegende Text in eine HREF... Anweisung eingeführt wird.
Der Cursor springt dann noch zur richtigen Stelle zur Eingabe
des Links (URL).
map ^X^W a< /A>^[bbbi< A HREF="http://#">^[F#
Dasselbe für ein Wort (statt der ganzen Zeile).
Man kann Macros verketten - dazu dient der "=" Befehl. Damit ist es möglich, einige ärgerliche Begrenzungen bezüglich der Länge eines Macros zu überwinden.
Der vi ist auch sehr praktisch beim Bearbeiten großer Mengen an
Files, z.B. wenn man 1000
Files "name.txt" nach " name.html"
umbenennen möchte:
Man öffnet den vi und geht in den Colon Mode:
:r !ls *.txt # xyz.txt :%s/.*/mv & &/ # mv xyz.txt xyz.txt :%s/txt$/html/ # mv xyz.txt xyz.html :w !sh :q!
Das sieht im Beispiel so aus:
Im VI, nach einlesen mit ":r !ls *":
plautze1.jpg plautze2.jpg plautze3.jpg plautze4.jpg plautze5.jpgHier der Befehl, der folgende Zeile erzeugt:
Jetzt hat man oft das Problem, daß man am Filenamen etwas ändern möchte, was nicht am Ende steht. Zb. sollen alle Files sapPEUvg3.out nach sapGAGvg3.out umbenannt werden. Man erzeugt also wie oben folgende vi-Datei:
mv sapPEUvg0.out sapPEUvg0.out mv sapPEUvg1.out sapPEUvg1.out mv sapPEUvg2.out sapPEUvg2.out mv sapPEUvg3.out sapPEUvg3.outJetzt muß man das zweite PEU jeder Zeile in GAG umschreiben; das macht einen Trick nötig, da vi die Zeilen von links nach rechts durchgeht. Daher kann man entweder jeweils die erste Instanz ändern, oder alle. Man ändert also alle PEU in einer Zeile in GAG, und ändert dann das erste GAG in PEU zurück:
:%s/PEU/GAG/g ==> alle Namen haben jetzt das GAG. :%s/GAG/PEU/ ==> nur das jeweils erste GAG auf der Zeile wird zum PEU.Man kann auch richtig professionel vorgehen und zuerst das erste PEU in GAG umbenennen und dann die Worte tauschen:
g/GAG/s/^\([^ ]*\) \([^ ]*\) \([^ ]*\)/\1 \3 \2/Das vertauscht auf jeder Zeile, die "GAG" enthält, das zweite mit dem dritten Wort; man erhält das gewünschte File und kann die Files umbennen.
Wenn man weiss, was man tut, dann kann man sich den Umweg über den vi sparen:
ls -d *.xxx | sed "s/.*\)\.xxx$/mv ' '\1.old'/" | sh Macht aus File bla.xxx das File bla.old. ls -d | sed "s/[A-Z,a-z,0-9,.,_,-]*/mv '&' '&.html'/" | sh
[ Allgemein | UNIX | AIX | TCP-IP | TCP | ROUTING | DNS | NTP | NFS | FreeBSD | Linux | RPi | SMTP | Tracing | GPS | LW ]
Copyright 2001-2021 by Orm Hager - Es gilt die GPL