Vim: Fügen Sie dieselben Zeichen über mehrere Zeilen ein


306

Manchmal möchte ich einen bestimmten visuellen Textblock über mehrere Zeilen hinweg bearbeiten.

Zum Beispiel würde ich einen Text nehmen, der so aussieht:

name
comment
phone
email

Und lass es so aussehen

vendor_name
vendor_comment
vendor_phone
vendor_email

Derzeit würde ich es jetzt so machen ...

  1. Wählen Sie alle 4 Zeilenzeilen eines Blocks durch Drücken von Vund dann jviermal aus.
  2. Einrücken mit >.
  3. Gehen Sie einen Brief mit zurück h.
  4. Gehen Sie zum Blockieren des visuellen Modus mit Ctrlv.
  5. Wählen Sie vier Zeilen aus, indem Sie jviermal drücken . Zu diesem Zeitpunkt haben Sie 4x1 visuelle Leerzeichenblöcke (vier Zeilen und eine Spalte) ausgewählt.
  6. Drücken Sie C. Beachten Sie, dass dies ziemlich links von einer Spalte eingerückt ist.
  7. Geben Sie a " vendor_"ohne Anführungszeichen ein. Beachten Sie den zusätzlichen Platz, den wir zurücklegen mussten.
  8. Drücken Sie Esc. Dies ist eines der wenigen Male, mit denen ich den EscEinfügemodus verlasse. Ctrlcwürde nur die erste Zeile bearbeiten.
  9. Wiederholen Sie Schritt 1.
  10. In die andere Richtung einrücken mit <.

Ich muss nicht einrücken, wenn vor den Wörtern mindestens eine Spalte mit Leerzeichen steht. Ich würde das Leerzeichen nicht brauchen, wenn ich den visuellen Block nicht mit löschen müsste c.

Aber wenn ich löschen muss, gibt es dann eine Möglichkeit, das zu tun, was ich oben ausgeführt habe, ohne das erforderliche Leerzeichen mit Einrückung zu erstellen?

Warum funktioniert das gleichzeitige Bearbeiten mehrerer Zeilen nur, wenn Sie den Einfügemodus mit Escover verlassen Ctrlc?


Hier ist ein komplizierteres Beispiel:

name    = models.CharField( max_length = 135 )
comment = models.TextField( blank = True )
phone   = models.CharField( max_length = 135, blank = True )
email   = models.EmailField( blank = True )

zu

name    = models.whatever.CharField( max_length = 135 )
comment = models.whatever.TextField( blank = True )
phone   = models.whatever.CharField( max_length = 135, blank = True )
email   = models.whatever.EmailField( blank = True )

In diesem Beispiel würde ich den vertikalen visuellen Block über dem ausführen .und ihn dann im Einfügemodus wieder einfügen, dh eingeben .whatever.. Hoffentlich können Sie jetzt den Nachteil dieser Methode sehen. Ich beschränke mich darauf, nur eine Textspalte auszuwählen , die in vertikaler Position alle gleich sind .


9
Besserer Weg: ":% s / ^ / vendor_ /"
Paul Tomblin

1
Danke für die Antwort. Das funktioniert, wenn ich nur ein Wort an jede Zeile anhängen möchte. Aber die Methode, die ich benutze, kann an jeder Position durchgeführt werden. Lassen Sie mich ein weiteres Beispiel mit einem komplizierteren Beispiel hinzufügen.
hobbes3

3
Markieren Sie dann die Zeilen, die Sie mit Shift-V ändern möchten, und geben Sie einen geeigneten Such- und Ersetzungsbefehl ein - im zweiten Beispiel:s/models\./\0whatever./
Paul Tomblin

Viele Möglichkeiten, um das oben genannte zu erreichen. Um alle Teile der Frage vollständig zu beantworten, funktioniert Teil 1) entweder Regex oder visueller Modus, den ich bearbeite, gut, wie in den Antworten angegeben (ich bevorzuge die visuelle Auswahl in GVIM). Für Teil 2) ist das Makro vielleicht am einfachsten, wie es von Brian Neal angeboten wird. Die beste Ressource, die ich für all diese Arten von "How tos" kenne, ist Practical Vim von Drew Neil. Hervorragende Schnelllesung und leichte Referenz, wenn Sie eine Formel vergessen. Hoffe, diese Empfehlung hilft jemandem, es wird sich für viele vim-Benutzer lohnen.
Arcseldon

@ Paul: Und wenn Sie das Zählen Tastenanschläge , könnten Sie ersetzen \0mit &.
icktoofay

Antworten:


912
  1. Bewegen Sie den Cursor auf die nin name.
  2. Aktivieren Sie den visuellen Blockmodus ( Ctrlv).
  3. Drücken Sie jdreimal (oder 3j).
  4. Drücken Sie I(Großbuchstabe i).
  5. Geben Sie ein vendor_. Hinweis: Der Bildschirm wird nur in der ersten Zeile aktualisiert - bis Escgedrückt wird (6.). An diesem Punkt werden alle Zeilen aktualisiert.
  6. Drücken Sie Esc.

Mini-Screencast zur Demonstration der Methode

Ein Groß Imuss eher als ein Klein verwendet werden i, weil die Klein ials Beginn eines interpretiert Textobjekt , das auf seinem eigenen ziemlich nützlich ist, zB für die in einem Tag - Block Auswahl ( it):

Mini-Screencast, der die Nützlichkeit des 'it'-Textobjekts zeigt


12
Ich konnte dies unter Windows nicht zum Laufen bringen (da STRG + V für das Einfügen in die Zwischenablage zugeordnet ist). Vim hat dies jedoch auch Strg + Q für die Windows-Version zugeordnet.
Arnestig

2
@Ven: Vim ist während dieser Zeit nicht wirklich beschäftigt - es wartet nur darauf, dass Sie eine andere Taste drücken und schließlich eine Zeitüberschreitung feststellen. Zwei Experimente für Sie: Versuchen Sie zuerst, die Escape-Taste zu drücken und dann sofort eine andere Taste wie joder zu drücken ^L. Sie sollten sehen, dass Vim doch nicht beschäftigt war; es wartete nur. Versuchen Sie zweitens, 'timeout'auf einen niedrigeren Wert wie 80(anstelle des Standardwerts 1000) zu wechseln , und stellen Sie fest, dass das Zeitlimit schneller abläuft.
icktoofay

1
@icktoofay Es sieht so aus, als ob die Variable, die Sie setzen möchten, timeoutlennicht ist timeout.
Jez

4
@ANjaNA: Wenn sich alle Stellen, an denen Sie einfügen möchten, in derselben Spalte befinden (z. B. wenn die Zahlen alle dieselbe Länge haben), können Sie dieselbe Technik verwenden, außer dass Sie Astatt drücken I, was nach dem ausgewählten Block statt zuvor eingefügt wird. Wenn Ihre Linien jedoch unterschiedlich lang sind, funktioniert dies nicht. Ich verwende dafür gerne eine Substitution, die mit dem Ende jeder Zeile übereinstimmt, z. B. einige Zeilen auswählen und verwenden :s/$/inserted/.
icktoofay

3
Ich musste den Pfeil nach unten drücken, nachdem ich
esc

69

Ein anderer Ansatz besteht darin, den Befehl .( dot) in Kombination mit zu verwenden I.

  1. Bewegen Sie den Cursor an die Stelle, an der Sie beginnen möchten
  2. Drücken Sie I
  3. Geben Sie in dem Präfix Sie wollen (zB vendor_)
  4. Drücken Sie esc.
  5. Drücken Sie j, um eine Zeile nach unten zu gehen
  6. Geben Sie ein ., um die letzte Bearbeitung zu wiederholen, und fügen Sie das Präfix automatisch erneut ein
  7. Wechseln Sie schnell zwischen jund.

Ich finde diese Technik ist oft schneller als der optische Block - Modus für eine kleine Anzahl von Ergänzungen und hat den zusätzlichen Vorteil , dass , wenn Sie nicht den Text auf jeder einzelne Zeile in einem Bereich eingelegt werden muss man sich einfach überspringen kann durch Drücken Extra j‚s .

Beachten Sie, dass für eine große Anzahl zusammenhängender Ergänzungen der Blockansatz oder das Makro wahrscheinlich überlegen ist.


Schön, einen anderen Ansatz zu sehen.
Ibn Saeed

Ich bevorzuge dies nur für ein paar Zeilen. IMO viel einfacher auszuführen.
Dan Bechard

Müssen Sie nach Eingabe des gewünschten Präfixes nicht die Escape-Taste drücken?
Iamnotsam

41
  1. Wählen Sie die Zeilen aus, mit denen Sie Änderungen vornehmen möchten CtrlV.
  2. Drücken Sie:

    • I: Einfügen vor der Auswahl.
    • A: Nach der Auswahl anhängen.
    • c: Ersetzen Sie die ausgewählten Elemente.
  3. Geben Sie den neuen Text ein.

  4. Drücken Sie Esc, um die Änderungen auf alle ausgewählten Zeilen anzuwenden.

4
Ausgezeichnet! Ich möchte nur den letzten Schritt Escfür VIM-Noobs wie mich hervorheben - es hat eine Weile gedauert, bis ich herausgefunden habe, dass die Änderungen "später" weitergegeben werden!
Bugs Bunny

1
Schön, wusste auch nichts über die Optionen "A" und "C".
hobbes3

Warum funktioniert das nicht v? Ich kann es damit machen Ctrl+V --> A, aber vdas Auswählen des Textes funktioniert nicht - wird Anur an diese Zeile angehängt. Sind sie nicht beide Auswahl? Auch sehr seltsam - wird Anur an das Zeilenende angehängt, wenn ich den visuellen Block bis zum Zeilenende erweitere; Andernfalls wird an jeder Stelle angehängt, an der der visuelle Block für jede Zeile endet. Es ist, als würde es keinen Unterschied zwischen aund erkennen A.
Alex G

1
Ich musste cstattdessen verwenden C, aber es funktionierte einwandfrei. Vielen Dank
Tarol

29

Ich würde ein Makro verwenden, um meine Aktionen aufzuzeichnen und es dann wiederholen.

  1. Setzen Sie den Cursor auf den ersten Buchstaben im Namen .
  2. Drücken Sie qq, um die Aufnahme in den q-Puffer zu starten.
  3. Hit igehen in den Einfügemodus, Typ vector_ , und drücken Sie dann EscInsert - Modus zu verlassen.
  4. Drücken Sie jetzt 0, um zum Zeilenanfang zurückzukehren.
  5. Jetzt drücken j, um nach unten zu gehen.
  6. Drücken Sie jetzt qerneut, um die Aufnahme zu beenden.

Sie haben jetzt ein schönes Makro.

Geben Sie ein 3@q, um Ihr Makro dreimal auszuführen und den Rest der Zeilen auszuführen.


Ist "q" etwas Besonderes (für "schnelles Makro"?)?
Peter Mortensen

Wie kann das Makro dauerhaft gemacht werden (über mehrere Sitzungen hinweg arbeiten)?
Peter Mortensen

@PeterMortensen Vim verfügt über eine Funktion namens Sitzungen, die Puffer (und viele andere Dinge) beibehält, die Sie untersuchen können.
Brian Neal

27
:%s/^/vendor_/

oder fehlt mir etwas


Sie vermissen die Tatsache, dass es sich wahrscheinlich um einen Untertext in einer Datei mit vielen anderen Zeilen handelt, in denen das vender_Präfix unerwünscht ist.
Dan Bechard

9
@dan Wenn nur ein Untertext benötigt wird, können Sie die Suche auf eine Reihe von Zeilennummern beschränken, z. B.1,4s/^/vendor_/
Brad Koch

1
@BradKoch Interessant. Ich war mir der Einschränkungen der Zeilennummer nicht bewusst, danke dafür.
Dan Bechard

8
Es ist interessant, aber praktischer ist es, die Auswahl mit Vund die Eingabe visuell zu blockieren :. Es wird dem ed-Ausdruck vorangestellt, mit :'<,'>dem der ed nur für die Auswahl gilt:'<,'>s/^/vendor_/
Dolanor

12

Aktualisiert Januar 2016

Die akzeptierte Antwort ist zwar eine großartige Lösung, dies sind jedoch etwas weniger Tastenanschläge und die Skalierung ist besser - im Prinzip basierend auf der akzeptierten Antwort.

  1. Bewegen Sie den Cursor auf die nin name.
  2. Aktivieren Sie den visuellen Blockmodus ( ctrlv).
  3. Drücken Sie 3j
  4. Drücken Sie I.
  5. Geben Sie ein vendor_.
  6. Drücken Sie esc.

visuelle Darstellung

Beachten Sie, dass dies weniger Tastenanschläge als die akzeptierte Antwort enthält (vergleiche Schritt 3). Wir zählen nur die Anzahl der auszuführenden j Aktionen.

Wenn Sie Zeilennummern aktiviert haben (wie oben dargestellt) und die Zeilennummer kennen, zu der Sie wechseln möchten, kann Schritt 3 in # geändert werden, Gwobei # die gewünschte Zeilennummer ist.

In unserem obigen Beispiel wäre dies 4G. Bei nur wenigen Zeilennummern funktioniert eine explizite Zählung jedoch gut.


7

Ich wollte viele Zeilen in einer Konfigurationsdatei auf einem Server auskommentieren, der nur vi (kein Nano) hatte, daher war die visuelle Methode ebenfalls umständlich. So habe ich das gemacht.

  1. Datei öffnen vi file
  2. Zeilennummern anzeigen :set number!oder:set number
  3. Verwenden Sie dann die Zeilennummern, um den Zeilenanfang durch "#" zu ersetzen. Wie?

:35,77s/^/#/

Hinweis: Die Nummern sind inklusive, Zeilen von 35 bis 77, beide enthalten werden geändert.

Um dies zu kommentieren / rückgängig zu machen, verwenden Sie einfach :35,77s/^#//

Wenn Sie nach jeder Codezeile ein Textwort als Kommentar hinzufügen möchten, können Sie auch Folgendes verwenden:

:35,77s/$/#test/ (für Sprachen wie Python)

:35,77s/;$/;\/\/test/ (für Sprachen wie Java)

Credits / Referenzen:

  1. /unix/84929/uncommenting-multiple-lines-of-code-specified-by-line-numbers-using-vi-or-vim

  2. /unix/120615/how-to-comment-multiple-lines-at-once


Dies war die perfekte Lösung für mich, da ich oft nur vim-tiny benutze.
JSON C11

7

Möglicherweise haben Sie auch einen Anwendungsfall, in dem Sie einen Textblock löschen und ersetzen möchten.

So was

Hello World

Hello World

Zu

Hello Cool

Hello Cool

Sie können einfach visuell in beiden Zeilen "Welt" auswählen.

Geben Sie cfür den Wandel - jetzt werden Sie in Insert - Modus sein.

Fügen Sie das gewünschte Material ein und klicken Sie auf Escape.

Beide werden vertikal reflektiert. Es funktioniert genau wie 'I', außer dass es den Block durch den neuen Text ersetzt, anstatt ihn einzufügen.


6

Angenommen, Sie haben diese Datei:

something

name
comment
phone
email

something else
and more ...

Sie möchten "vendor_" vor "name", "comment", "phone" und "email" hinzufügen, unabhängig davon, wo sie in der Datei angezeigt werden .

:%s/\<\(name\|comment\|phone\|email\)\>/vendor_\1/gc

Das cFlag fordert Sie zur Bestätigung auf. Sie können das löschen, wenn Sie die Eingabeaufforderung nicht möchten.


5

Eine Alternative, die flexibler sein kann:

Beispiel: Geben Sie den Text XYZ am Zeilenanfang ein

:%norm IXYZ

Was passiert hier?

  • % == In jeder Zeile ausführen
  • norm == Führen Sie die folgenden Tasten im normalen Modus aus
  • I == Am Zeilenanfang einfügen
  • XYZ == Der Text, den Sie eingeben möchten

Dann drückst du Enterund es wird ausgeführt.

Speziell für Ihre Anfrage:

:%norm Ivendor_

Sie können auch einen bestimmten Bereich auswählen:

:2,4norm Ivendor_

Oder über einen ausgewählten Sichtbereich ausführen:

:'<,'>norm Ivendor_

1
Ist es möglich, im Einfügemodus (Norm Iabc <ESC>) Schlüsselsequenzen wie <Esc> zu senden, um interessantere Dinge zu tun?
Batbrat

1
@ Batbrat Ich habe das gerade herausgefunden! Sie können drücken ctrl-v ctrl-[, um ein "Escape Esc" einzufügen, das Sie für den Zweck Ihres normalen Befehls in den "normalen Modus" zurückversetzt. Ich habe das gerade mit getestet '<,'>norm Iaa^[ysiw", wo ^[ist der entkommene Esc.
Aubrey Lavigne

4
Use Ctrl+V to enter visual block mode
Move Up/Down to select the columns of text in the lines you want to comment.
Then hit Shift+i and type the text you want to insert.
Then hit Esc, wait 1 second and the inserted text will appear on every line

Funktioniert diese Methode für alle Versionen von vim oder sind vim-Plugins erforderlich? Der Grund, warum ich frage, ist b / c, es funktioniert manchmal auf einigen Maschinen, aber manchmal nicht. Ich kann den Unterschied nicht herausfinden. VIM, das mit Git unter Windows geliefert wird - ich kann es nicht zum Laufen bringen. Auf einigen Ubuntu- und Centos-Linux-Computern kann ich es nicht zum Laufen bringen. Ich hatte in einigen seltenen Fällen Erfolg, aber ich konnte den Erfolg nicht reproduzieren. Es ist ein Mysterium. nichts scheint zu passieren, nachdem ich ESC getroffen habe.
Davidj411

Seltsamerweise funktioniert es jetzt für mich. nichts hat sich geändert, außer vielleicht den Sternen :) Als ich nach einer Lösung für mein Problem suchte, habe ich auf dieser Seite etwas gefunden, das etwas erwähnt, nach dem in vim gesucht werden muss. vim.wikia.com/wiki/Inserting_text_in_multiple_lines Überprüfen Sie in Vim, ob Sie es haben Die Funktion für blockweise Operatoren (I, A und mehr) durch Eingabe des Befehls: version. Die Ausgabe sollte + visualextra enthalten.
Davidj411

Ich wollte generell einen Kommentar hinzufügen, nicht zu Ihrer Antwort. Die meisten dieser Antworten sagen dasselbe, verwenden jedoch unterschiedliche Wörter. Meins hatte etwas anderes zu bieten und enthielt einen Link.
Davidj411

2
  1. Ctrl + v, um in den visuellen Blockmodus zu wechseln
  2. Wählen Sie die Linien mit dem Aufwärts- und Abwärtspfeil aus
  3. Geben Sie Kleinbuchstaben ein 3i(drücken Sie dreimal Kleinbuchstaben I )
  4. I(Drücken Sie die Großschreibung I. Dadurch gelangen Sie in den Einfügemodus.)
  5. Schreiben Sie den Text, den Sie hinzufügen möchten
  6. Esc
  7. Drücken Sie den Abwärtspfeil
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.