Suchen und ersetzen Sie Zeichenfolgen in vim in mehreren Zeilen

352

Ich kann :%s/<search_string>/<replace_string>/geine Zeichenfolge in einer Datei :s/<search_string>/<replace_string>/ersetzen oder in der aktuellen Zeile ersetzen.

Wie kann ich Wörter aus ausgewählten Zeilen in vim auswählen und ersetzen?

Beispiel: Ersetzen Sie Text aus Zeilen 6-10, 14-18aber nicht aus 11-13.

mu 無
quelle

Antworten:

254

Der :&&Befehl wiederholt die letzte Ersetzung mit denselben Flags. Sie können die zusätzlichen Bereiche angeben (und so viele verketten, wie Sie möchten):

:6,10s/<search_string>/<replace_string>/g | 14,18&&

Wenn Sie jedoch viele Bereiche haben , würde ich lieber eine Schleife verwenden:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor
Ingo Karkat
quelle
5
Vielen Dank. Hinweis für zukünftige Benutzer - :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&funktioniert auch, forSchleife erleichtert das Erinnern und Ausführen.
mu 無
5
Froh, dass Sie es mögen! Der :Befehl für die nachfolgenden Befehle ist übrigens optional, sodass Sie weitere Tastenanschläge speichern können.
Ingo Karkat
2
:&&spart mir Hunderte von Tastenanschlägen pro Woche. Vielen Dank!
pdoherty926
Es funktioniert ohne das 'g' am Ende in meinem vim. Wenn Sie also den Linienbereich angeben, wird möglicherweise kein globales Flag benötigt
Tayyar R
3
@TayyarR Der Bereich deckt die Linien ab (sozusagen vertikal), während das Flag 'g' bestimmt, ob nur eine oder alle Übereinstimmungen innerhalb der Linie (also horizontal) ersetzt werden.
Ingo Karkat
385

Alles ersetzen:

:%s/foo/bar/g

Suchen Sie jedes Vorkommen von 'foo' (in allen Zeilen) und ersetzen Sie es durch 'bar'.

Für bestimmte Zeilen:

:6,10s/foo/bar/g

Ändern Sie jedes 'foo' für alle Zeilen von Zeile 6 bis einschließlich Zeile 10 in 'bar'.

Jayanth Ramachandran
quelle
3
Was ist der Zweck von / g hier? Entschuldigung, ich bin neu in Linux
Raja Anbazhagan
4
@RajaAnbazhagan Im letzten Teil dieses Ausdrucks nach dem letzten /geben Sie Flags für die Operation an. Dieser Befehl ersetzt normalerweise die erste Übereinstimmung in einer Zeile. Mit dem gFlag werden alle Vorkommen ersetzt.
Litty
17
Sie sollten wirklich auf Ihre Quellen verweisen (z. B. vim.wikia.com/wiki/Search_and_replace), wenn Sie die Arbeit einer anderen Person kopieren und einfügen möchten.
Andrew S
2
Das %Ding macht die Arbeit! Ansonsten ist es nur das erste Vorkommen.
Santosh Kumar
7
%=> Führen Sie diesen Befehl in allen Zeilen aus. g=> mehrere Vorkommen in derselben Zeile abgleichen.
Shaahiin
55

Als Randnotiz, anstatt die Zeilennummern eingeben zu müssen, markieren Sie einfach die Zeilen, die Sie in einem der visuellen Modi suchen / ersetzen möchten:

  • VISUALmode ( V)
  • VISUAL BLOCKModus ( Ctrl+ V)
  • VISUAL LINEModus ( Shift+ V, funktioniert am besten in Ihrem Fall)

Geben Sie nach Auswahl der zu ersetzenden Zeilen den folgenden Befehl ein:

:s/<search_string>/<replace_string>/g

Sie werden feststellen, dass der Bereich '<,'>automatisch für Sie eingefügt wird:

:'<,'>s/<search_string>/<replace_string>/g

Hier '<bedeutet einfach die erste hervorgehobene Zeile und '>die letzte hervorgehobene Zeile .

Beachten Sie, dass das Verhalten im NORMALModus möglicherweise unerwartet ist : '<und '>zeigen Sie auf den Anfang und das Ende der letzten Hervorhebung in einem der VISUALModi. Stattdessen kann im NORMALModus die spezielle Zeilennummer .verwendet werden, was einfach aktuelle Zeile bedeutet . Daher können Sie nur in der aktuellen Zeile wie folgt suchen / ersetzen:

:.s/<search_string>/<replace_string>/g

Beachten Sie außerdem, dass das Einfügen einer Sekunde :zwischen dem Bereich und dem Befehl find / replace keinen Schaden anrichtet. Mit anderen Worten, diese Befehle funktionieren weiterhin:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g
Attila O.
quelle
1
> Beispiel: Ersetzen Sie Text aus den Zeilen 6-10, 14-18, aber nicht aus 11-13. - Beantwortet Ihre Antwort nicht genau diese Frage?
Poige
27

Sie können dies mit zwei Such- / Ersetzungssequenzen tun

  :6,10s/<search_string>/<replace_string>/g
  :14,18s/<search_string>/<replace_string>/g

Das zweite Mal müssen Sie nur den Bereich anpassen. Anstatt alles auszutippen, würde ich mich an den letzten Befehl erinnern und nur den Bereich bearbeiten

Lieven Keersmaekers
quelle
20

Wenn Sie in vim verwirrt sind, welche Zeilen betroffen sind, verwenden Sie unten

 :%s/foo/bar/gc  

Ändern Sie jedes 'foo' in 'bar', aber bitten Sie zuerst um Bestätigung. Drücken Sie 'y' für Ja und 'n' für Nein. Vergessen Sie nicht, danach zu speichern

:wq
SMJ
quelle
1
Sie können das cFlag zusätzlich zur Angabe des Bereichs verwenden, :6,10s/<search_string>/<replace_string>/cfunktioniert also. csteht für confirm. Ich benutze die cFlagge ziemlich oft, um zu verhindern, dass versehentlich Wörter ersetzt werden, bei denen ich nicht daran gedacht habe, dass sie auch dort existieren.
Wolfson
16

Beispiele für das Suchen und Ersetzen von VI-Befehlen

Angenommen, Sie möchten ein Wort namens "foo" finden und durch "bar" ersetzen.

Drücken Sie zuerst die [Esc]Taste

%s/foo/bar/Geben Sie Folgendes ein: (Doppelpunkt) gefolgt von und drücken Sie die [Eingabetaste]

:%s/foo/bar/

Arnav
quelle
11
Ihr :%s/<search_string>/<replace_string>/gBefehl ersetzt alle Vorkommen in der gesamten Datei. Nicht gerade die Antwort auf die Frage, aber dennoch nützlich :)
Tanius
@tanius Eigentlich war es die direkteste Antwort auf mein Problem. Sie können die Frage in "Suchen und Ersetzen von Zeichenfolgen in vim in" Ausgewählten "Zeilen"
ändern
9

Wir müssen uns nicht die Mühe machen, die aktuelle Zeilennummer einzugeben.

Wenn Sie jeweils foodie baraktuelle Zeile ( .) und die beiden nächsten Zeilen ( +2) ändern möchten , gehen Sie einfach wie folgt vor :

:.,+2s/foo/bar/g

Wenn Sie bestätigen möchten, bevor Änderungen vorgenommen werden, ersetzen Sie diese gdurch gc:

:.,+2s/foo/bar/gc
Lingjiankong
quelle
Eine andere nette Sache, die ich oft benutze, ist :.,$s/foo/bar/gcdas Suchen und Ersetzen von der aktuellen Zeile bis zum Ende der Datei.
Wolfson
3

Suchen und ersetzen

:%s/search\|search2\|search3/replace/gci

g => globale Suche

c => Bitten Sie zuerst um Bestätigung

i => Groß- und Kleinschreibung wird nicht berücksichtigt

Wenn Sie einen direkten Austausch ohne Bestätigung wünschen, verwenden Sie den folgenden Befehl

:%s/search/replace/g

Wenn Sie für jedes Ersetzen eine Bestätigung wünschen, führen Sie den folgenden Befehl aus

:%s/search/replace/gc

Bitten Sie zuerst um Bestätigung. Bei dieser Suche wird die Groß- und Kleinschreibung nicht berücksichtigt.

:%s/search/replace/gci
Rahul Ravi
quelle
1

Das Festlegen des Bereichs durch visuelle Auswahl ist in Ordnung, aber wenn es sehr einfache Operationen über nur ein paar Zeilen gibt, die von einem Operator ausgewählt werden können, ist es am besten, diese Befehle als Operatoren anzuwenden.

Dies kann leider nicht über Standard-Vim-Befehle erfolgen. Sie könnten eine Art Workaround mit dem! (Filter-) Operator und jedes Textobjekt. Um die Operation beispielsweise auf einen Absatz anzuwenden, haben Sie folgende Möglichkeiten:

!ip

Dies muss als "Anwenden des Operators! Innerhalb eines Absatzes" gelesen werden. Der Filteroperator startet den Befehlsmodus und fügt automatisch den Zeilenbereich gefolgt von einem Literal "!" Ein. dass Sie gleich danach löschen können. Wenn Sie dies anwenden, auf den folgenden Absatz:

1
2  Repellendus qui velit vel ullam!
3  ipsam sint modi! velit ipsam sint
4  modi! Debitis dolorum distinctio
5  mollitia vel ullam! Repellendus qui
6  Debitis dolorum distinctio mollitia
7  vel ullam! ipsam
8
9  More text around here

Das Ergebnis nach dem Drücken von "! Ap" wäre wie folgt:

:.,.+5

Als die '.' (Punkt) bedeutet, dass die aktuelle Linie, der Bereich zwischen der aktuellen Linie und den 5 Linien danach für die Operation verwendet wird. Jetzt können Sie den Ersatzbefehl auf die gleiche Weise wie zuvor hinzufügen.

Der schlechte Teil ist, dass dies nicht einfacher ist, als den Text für letzteren auszuwählen, der den Operator anwendet. Der gute Teil ist, dass dies das Einfügen des Bereichs für andere ähnliche Textbereiche (in diesem Fall Absätze) mit deutlich unterschiedlicher Größe wiederholen kann. Dh wenn Sie später den Bereich größeren Absatz wählen möchten, das '.' Wille dazu richtig.

Wenn Sie die Idee mögen, semantische Textobjekte zur Auswahl des Operationsbereichs zu verwenden, können Sie auch mein Plugin EXtend.vim überprüfen , das das Gleiche tun kann, aber auf einfachere Weise.

Saul Axel Martinez Ortiz
quelle
0

Um diese Frage zu beantworten:

:40,50s/foo/bar/g

Ersetzen Sie foo durch einen Balken in diesen Zeilen zwischen der 40. Zeile und der 50. Zeile (einschließlich). Wenn Sie diesen Befehl ausführen, können Sie ihn derzeit in einer beliebigen Zeile eingeben.

:50,40s/foo/bar/g

funktioniert auch, vim wird Sie um Bestätigung bitten und dann den Ersatz für Sie vornehmen, als hätten Sie den ersten Befehl eingegeben.

:,50s/foo/bar/g

Ersetzen Sie foo durch einen Balken in diesen Zeilen zwischen der Zeile, in der Sie sich gerade befinden, und der 50. Zeile (einschließlich). (Wenn Sie sich in einer Zeile befinden, nachdem die 50. Zeile vim erneut um Bestätigung gebeten hat)

Um den Unterschied zwischen vim und dem Vrapper-Plugin von Eclipse zu verdeutlichen:

Beachten Sie, dass in Varpper

:,50s/foo/bar/g Befehl wird NICHT funktionieren.

:50,40s/foo/bar/g wird funktionieren, ohne um Bestätigung zu bitten.

(Für Vrapper Version 0.74.0 oder älter).

ZhaoGang
quelle
-5
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal
/sys/sim/source/gm/kg/jl/ls/owow/lsal

Angenommen, Sie möchten das oben Gesagte durch andere Informationen ersetzen.

COMMAND(:%s/\/sys\/sim\/source\/gm\/kg\/jl\/ls\/owow\/lsal/sys.pkg.mpu.umc.kdk./g)

In diesem Fall wird das oben Gesagte durch ( sys.pkg.mpu.umc.kdk.) ersetzt.

Sai Ganesh
quelle
Ich bin mir nicht sicher, ob dies tatsächlich die Frage beantwortet. Aus der Frage geht hervor, dass die fragende Person bereits weiß, wie %sEingaben geändert werden sollen, aber wissen möchte, wie dies "semi-global" zu tun ist (dh seine Spezifikation lautet Zeilen 6-10 und 14-18, jedoch nicht in den Zeilen 11-). 13).
Brandon Buck
1
Was ist auch "BEFEHL"? Und Sie leiden an einem Zahnstochersyndrom .
Martin Tournoij
Um dieses Syndrom zu heilen, können Sie ein anderes Zeichen als Trennzeichen verwenden anstelle des Standard /, zum Beispiel !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE