Suchen und ersetzen Sie in vim in bestimmten Zeilen


91

ich kann nutzen

:5,12s/foo/bar/g

fooum es barzwischen den Zeilen 5 und 12 zu suchen und zu ersetzen . Wie kann ich das nur in Zeile 5 und 12 tun (und nicht in den Zeilen dazwischen)?

Antworten:


72

Vim hat spezielle Atome mit regulären Ausdrücken, die in bestimmten Zeilen, Spalten usw.; Sie können sie (möglicherweise zusätzlich zum Bereich) verwenden, um die Übereinstimmungen zu begrenzen:

:5,12s/\(\%5l\|\%12l\)foo/bar/g

Sehen :help /\%l


8
Ein komplizierterer Weg als ich erwartet hatte, aber meine Frage perfekt beantwortet. Vielen Dank!
— Pfnuesel

55

Sie können die Ersetzung in Zeile 5 durchführen und in Zeile 12 mit minimalem Aufwand wiederholen:

:5s/foo/bar
:12&

Vergisst, wie Ingo :&betont hat, Ihre Flaggen. Da Sie verwenden /g, wäre der richtige Befehl :&&:

:5s/foo/bar/g
:12&&

Sehen :help :&und Freunde.


10
+1 für die :&Verwendung des Obskuren . Wenn es Flags ( s/../../g) gibt, muss man :&&allerdings ...
— Ingo Karkat

10
@IngoKarkat, um fair zu sein, denke ich \(\%5l\|\%12l\)ist dunkler als:&
— doubleDown

13

Sie können immer ein cam Ende hinzufügen . Dies wird für jedes Spiel eine Bestätigung verlangen.

:5,12s/foo/bar/gc

1
Dies kann ein Albtraum sein, wenn zwischen den Zeilen 5 und 12 viele Übereinstimmungen liegen (denken Sie daran, dass eine gFlagge im Spiel ist)
— doubleDown

1
@doubleDown Dies ist keine universelle Lösung (wo es viele mögliche Kandidaten gibt), aber in den meisten Fällen ist es wirklich lästiger, n5 oder 6 Mal zu drücken, als \(\%5l\|\%12l\)die Ersatzanweisung hinzuzufügen ?
— Dean

Ich finde das nützlich, ich wollte jede andere Zeile ändern, das wäre schneller gewesen als das, was ich letztendlich getan habe.
— Tiktak

8

Interessante Frage. Es scheint, als gäbe es nur eine Bereichsauswahl und keine Mehrzeilenauswahl:

http://vim.wikia.com/wiki/Ranges

Wenn Sie jedoch in Zeile 5 und 12 etwas Besonderes haben, können Sie den :gOperator verwenden. Wenn Ihre Datei so aussieht (Zahlen nur als Referenz):

 1     line one
 2     line one
 3     line one
 4     line one
 5     enil one
 6     line one
 7     line one
 8     line one
 9     line one
10     line one
11     line one
12     enil one

Und Sie wollen ersetzen onedurch enoauf den Linien , wo es enilstatt line:

:g/enil/s/one/eno/

5
Dies setzt tatsächlich viel
— voraus

1

Sie könnten edeinen zeilenorientierten Texteditor mit ähnlichen Befehlen wie vi und vim verwenden. Es ist wahrscheinlich älter als vi und vim.

In einem Skript (unter Verwendung eines Here-Dokuments, das Eingaben bis zur EndCommand-Markierung verarbeitet) würde es folgendermaßen aussehen:

ed file <<EndCommands
    5
    s/foo/bar/g
    7
    s/foo/bar/g
    wq
EndCommands

Natürlich können die ed-Befehle auch in der Befehlszeile verwendet werden.


3
Ich sehe keinen Vorteil gegenüber der vimAlternative.
— Bernhard

1
Und das Gleiche kann auch mit Vim gemacht werden. Die Zahlen können tatsächlich vor das gesetzt werden :s, aber es gibt immer noch die Duplizierung des :sBefehls (was Romainls Lösung vermeidet).
— Ingo Karkat

Meiner Ansicht nach wollte der Benutzer möglicherweise mehr als zwei Zeilen zum Bearbeiten auswählen. In diesem Fall könnte ein nicht interaktiver Ansatz von Interesse gewesen sein - was AFAIK mit vim nicht möglich ist.
— Verdächtiger

1
Oh, Vim kann das (z. B. im "Ex" -Modus), aber Sie haben Recht, dass ein anderes Tool einem interaktiven Editor vorgezogen werden sollte. Meine Präferenz wäre jedoch sed...
— Ingo Karkat
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.