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.