Znajdź i zamień ciągi znaków w vimie na wielu liniach

352

Mogę zrobić, :%s/<search_string>/<replace_string>/gaby zamienić ciąg znaków w pliku lub :s/<search_string>/<replace_string>/zamienić w bieżącym wierszu.

Jak mogę wybrać i zamienić słowa z wybranych linii w vimie?

Przykład: zamień tekst z linii 6-10, 14-18ale nie z 11-13.

mu 無
źródło

Odpowiedzi:

254

:&&Komenda powtarza ostatnie zmiany z tymi samymi flagami. Możesz podać do niej dodatkowe zakresy (i połączyć dowolną ich liczbę):

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

Jeśli masz wiele zakresów , wolę użyć pętli:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor
Ingo Karkat
źródło
5
Dzięki. Uwaga dla przyszłych użytkowników - :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&będzie również działać, forpętla ułatwia zapamiętanie i wykonanie.
mu 無
5
Cieszę się że to lubisz! :Na kolejnych poleceń jest opcjonalne, btw, dzięki czemu można zaoszczędzić trochę więcej klawiszy.
Ingo Karkat
2
:&&zaoszczędzi mi setki naciśnięć klawiszy tygodniowo. Dzięki!
pdoherty926
Działa bez „g” na końcu w moim vimie. Może więc, kiedy podasz zakres linii, nie potrzebuje globalnej flagi
Tayyar R
3
@TayyarR Zakres obejmuje linie (że tak powiem) w pionie, podczas gdy flaga „g” określa, czy tylko jedno lub wszystkie dopasowania w linii (tak poziomo) są zastępowane.
Ingo Karkat
385

Zamień wszystko:

:%s/foo/bar/g

Znajdź każde wystąpienie „foo” (we wszystkich wierszach) i zamień je na „bar”.

Dla określonych linii:

:6,10s/foo/bar/g

Zmień każdy „foo” na „słupek” dla wszystkich linii od linii 6 do linii 10 włącznie.

Jayanth Ramachandran
źródło
3
jaki jest cel / g tutaj? Przepraszam, że jestem nowy w Linuksie
Raja Anbazhagan
4
@RajaAnbazhagan Ostatnią częścią tego wyrażenia, po ostatniej /, jest wskazanie flag dla operacji. To polecenie zwykle zastępuje pierwsze dopasowanie w linii; Z gflagą zastąpi wszystkie wystąpienia.
Litty
17
Powinieneś naprawdę odwoływać się do swoich źródeł (tj. Vim.wikia.com/wiki/Search_and_replace), jeśli zamierzasz skopiować i pominąć pracę innej osoby.
Andrew S
2
%Rzecz działa! W przeciwnym razie jest to tylko pierwsze wystąpienie.
Santosh Kumar
7
%=> uruchom to polecenie we wszystkich liniach. g=> dopasuj wiele wystąpień w tej samej linii.
Shaahiin,
55

Na marginesie, zamiast wpisywać numery linii, po prostu zaznacz linie, w których chcesz znaleźć / zamienić w jednym z trybów wizualnych:

  • VISUALtryb ( V)
  • VISUAL BLOCKtryb ( Ctrl+ V)
  • VISUAL LINEtryb ( Shift+ V, działa najlepiej w twoim przypadku)

Po wybraniu linii do zastąpienia wpisz polecenie:

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

Zauważysz, że zakres '<,'>zostanie wstawiony automatycznie:

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

Tutaj '<oznacza po prostu pierwszą podświetloną linię i '>oznacza ostatnią podświetloną linię .

Pamiętaj, że zachowanie może być nieoczekiwane w NORMALtrybie: '<i '>wskaż początek i koniec ostatniego podświetlenia wykonanego w jednym z VISUALtrybów. Zamiast tego w NORMALtrybie .można użyć specjalnego numeru linii , co oznacza po prostu bieżącą linię . Dlatego możesz znaleźć / zamienić tylko w bieżącym wierszu w następujący sposób:

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

Inną rzeczą do odnotowania jest to, że wstawienie sekundy :między zakresem a poleceniem znajdź / zamień nie szkodzi, innymi słowy, te polecenia będą nadal działać:

:'<,'>:s/<search_string>/<replace_string>/g
:.:s/<search_string>/<replace_string>/g
Attila O.
źródło
1
> Przykład: zamień tekst z linii 6-10, 14-18, ale nie z 11-13. - czy twoja odpowiedź nie odpowiada na to pytanie, prawda?
poige
27

Możesz to zrobić za pomocą dwóch sekwencji znajdź / zamień

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

Za drugim razem wszystko, co musisz dostosować, to zakres, więc zamiast wpisywać to wszystko, przypominam sobie ostatnie polecenie i edytuję tylko zakres

Lieven Keersmaekers
źródło
20

Jeśli jesteś zdezorientowany, które linie zostaną dotknięte, użyj poniżej

 :%s/foo/bar/gc  

Zmień każdy „foo” na „pasek”, ale najpierw poproś o potwierdzenie. Naciśnij „y” dla „tak” i „n” dla „nie”. Po tym nie zapomnij zapisać

:wq
SMJ
źródło
1
Możesz faktycznie użyć cflagi oprócz określenia zakresu, więc :6,10s/<search_string>/<replace_string>/cdziała. coznacza confirm. Używam cflagi dość często, aby nie dopuścić do przypadkowego zastąpienia słów, o których nie myślałem, że one również tam istnieją.
Wolfson
16

VI wyszukaj i zamień przykłady poleceń

Powiedzmy, że chcesz znaleźć słowo o nazwie „foo” i zastąpić je słowem „bar”.

Pierwszy [Esc]klawisz

Wpisz: (dwukropek), a następnie %s/foo/bar/naciśnij klawisz [Enter]

:%s/foo/bar/

arnav
źródło
11
Twoje :%s/<search_string>/<replace_string>/gpolecenie zastąpi wszystkie wystąpienia w całym pliku. Nie do końca odpowiedź na pytanie, ale mimo to przydatna :)
tanius
@tanius Właściwie to była najprostsza odpowiedź na mój problem. Możesz rozważyć zmianę pytania na „Znajdź i zamień ciągi w vimie w„ Wybranych ”wierszach
Omid N
9

Nie musimy zawracać sobie głowy wprowadzaniem bieżącego numeru linii.

Jeśli chcesz zmienić siebie foo, aby bardla bieżącej linii ( .) i dwóch kolejnych linii ( +2), po prostu zrobić:

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

Jeśli chcesz, aby potwierdzić przed dokonaniem tych zmian należy wymienić gz gc:

:.,+2s/foo/bar/gc
lingjiankong
źródło
Inną miłą rzeczą, której często używam, jest :.,$s/foo/bar/gcwyszukiwanie i zamiana, zaczynając od bieżącej linii aż do końca pliku.
Wolfson
3

Wyszukaj i zamień

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

g => globalne wyszukiwanie

c => Najpierw poproś o potwierdzenie

i => Bez rozróżniania wielkości liter

Jeśli chcesz bezpośredniej zamiany bez potwierdzenia, użyj poniższego polecenia

:%s/search/replace/g

Jeśli chcesz potwierdzić dla każdej zamiany, uruchom poniższe polecenie

:%s/search/replace/gc

Najpierw poproś o potwierdzenie, w wyszukiwaniu nie będzie rozróżniana wielkość liter.

:%s/search/replace/gci
Rahul Ravi
źródło
1

Określanie zakresu poprzez selekcję wizualną jest w porządku, ale gdy są bardzo proste operacje na kilku liniach, które może wybrać operator, najlepiej zastosować te polecenia jako operatory.

Niestety nie można tego zrobić za pomocą standardowych poleceń vima. Możesz zrobić coś w rodzaju obejścia za pomocą! (filtr) operator i dowolny obiekt tekstowy. Na przykład, aby zastosować operację do akapitu, możesz wykonać:

!ip

Należy to rozumieć jako „Zastosuj operator! Wewnątrz akapitu”. Operator filtru uruchamia tryb poleceń i automatycznie wstawia zakres wierszy, po których następuje dosłowne „!” które możesz usunąć zaraz po. Jeśli zastosujesz to, do następującego akapitu:

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

Wynik po naciśnięciu „! Ap” wyglądałby następująco:

:.,.+5

Jako „.” (punkt) oznacza bieżącą linię, zakres między bieżącą linią a 5 liniami później zostanie wykorzystany do operacji. Teraz możesz dodać polecenie zastępcze w taki sam sposób, jak poprzednio.

Złą stroną jest to, że nie jest to łatwiejsze niż wybranie tekstu dla drugiego operatora. Zaletą jest to, że może to powtórzyć wstawianie zakresu dla innych podobnych zakresów tekstu (w tym przypadku akapitów) o wyraźnie innym rozmiarze. To znaczy, jeśli później chcesz wybrać zakres większy akapit „.” do tego dobrze.

Ponadto, jeśli podoba Ci się pomysł użycia semantycznych obiektów tekstowych do wyboru zakresu operacji, możesz sprawdzić moją wtyczkę EXtend.vim, która może zrobić to samo, ale w łatwiejszy sposób.

Saul Axel Martinez Ortiz
źródło
0

Aby odpowiedzieć na to pytanie:

:40,50s/foo/bar/g

zamień foo na słupek w tych liniach między 40. i 50. linią (włącznie), po wykonaniu tego polecenia możesz obecnie znajdować się w dowolnej linii.

:50,40s/foo/bar/g

działa również, vim poprosi cię o potwierdzenie, a następnie wykona zamianę tak, jakbyś wprowadził pierwsze polecenie.

:,50s/foo/bar/g

zamień foo na pasek w tych liniach między linią, w której aktualnie się znajdujesz, a linią 50 (włącznie). (jeśli jesteś w linii PO 50-tej linii vim poprosi o potwierdzenie ponownie)

Aby wyjaśnić różnicę między vimem a vrapperową wtyczką Eclipse:

Zauważ, że w varpper

:,50s/foo/bar/g polecenie NIE zadziała.

:50,40s/foo/bar/g będzie działać bez pytania o potwierdzenie.

(Dla Vrapper w wersji 0.74.0 lub starszej).

ZhaoGang
źródło
-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

Załóżmy, że chcesz zastąpić powyższe innymi informacjami.

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

W tym powyższe zostanie zastąpione przez ( sys.pkg.mpu.umc.kdk.).

Sai Ganesh
źródło
Nie jestem pewien, czy to faktycznie odpowiada na pytanie. Z pytania wynika, że ​​osoba zadająca pytanie jest już świadoma, jak %smodyfikować dane wejściowe, ale chce wiedzieć, jak to zrobić „częściowo globalnie” (tzn. Jego specyfikacja to wiersze 6–10 i 14–18, ale nie wiersze 11– 13).
Brandon Buck
1
Co to jest „POLECENIE”? I cierpisz na zespół pochylonej wykałaczki .
Martin Tournoij,
Aby wyleczyć że zespół, można użyć innego znaku jako separatora zamiast domyślnego /, np !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE