Знайдіть і замініть рядки в vim у кількох рядках


352

Я можу зробити :%s/<search_string>/<replace_string>/gдля заміни рядка через файл або :s/<search_string>/<replace_string>/для заміни у поточному рядку.

Як я можу виділити та замінити слова з вибіркових рядків у vim?

Приклад: замініть текст рядками 6-10, 14-18але не від 11-13.



Відповіді:


254

:&&Команда повторює останню заміну з тими ж прапорами. Ви можете поставити йому додатковий асортимент (і об'єднати стільки, скільки вам потрібно):

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

Якщо у вас багато діапазонів , я б краще скористатися циклом:

:for range in split('6,10 14,18')| exe range 's/<search_string>/<replace_string>/g' | endfor

5
Дякую. Примітка для майбутніх користувачів - :6,10s/<search_string>/<replace_string>/g | :14,18&& | :20,23&& | :28,31&&також працюватиме, forцикл полегшує запам'ятовування та виконання.
mu 無

5
Радий, що тобі подобається! :На наступних команд НЕ є обов'язковим, до речі, так що ви можете заощадити ще кілька натискань клавіш.
Інго Каркат

2
:&&врятує мене сотні натискань клавіш на тиждень. Дякую!
pdoherty926

Це працює без "g" в кінці в моєму vim. Тож, можливо, коли ви вказуєте діапазон рядків, він не потребує глобального прапора
Tayyar R

3
@TayyarR Діапазон охоплює рядки (так би мовити вертикально), тоді як прапор 'g' визначає, чи замінено лише одне чи всі збіги в межах рядка (так горизонтально).
Інго Каркат

385

Замінити все:

:%s/foo/bar/g

Знайдіть кожне виникнення "foo" (у всіх рядках) та замініть його на "bar".

Для конкретних ліній:

:6,10s/foo/bar/g

Змініть кожен 'foo' на 'bar' для всіх рядків від рядка 6 до рядка 10 включно.


3
яка мета / г тут? Вибачте, я новачок у linux
Раджа Анбаджаган

4
@RajaAnbazhagan Заключна частина цього виразу, після останнього /, там, де ви вказуєте прапори для операції. Ця команда, як правило, замінить перший матч у рядку; З gпрапором він замінить усі події.
Літті

17
Ви дійсно повинні посилатися на свої джерела (наприклад, vim.wikia.com/wiki/Search_and_replace), якщо ви збираєтесь скопіювати та передати роботу іншої людини.
Андрій S

2
Справа %спрацьовує! Інакше це лише лише перше виникнення.
Сантош Кумар

7
%=> запустити цю команду у всіх рядках. g=> співставити кілька випадків в одному рядку.
Шаахіін

55

Як бічна примітка, замість того, щоб вводити номери рядків, просто виділіть рядки, де потрібно знайти / замінити в одному з візуальних режимів:

  • VISUALрежим ( V)
  • VISUAL BLOCKрежим ( Ctrl+ V)
  • VISUAL LINEрежим ( Shift+ V, найкраще працює у вашому випадку)

Вибравши рядки для заміни, введіть команду:

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

Ви зауважите, що діапазон '<,'>буде вставлено автоматично для вас:

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

Тут '<просто означає перший виділений рядок і '>означає останній виділений рядок .

Зауважте, що поведінка може бути несподіваною в NORMALрежимі: '<і '>вкажіть на початок і кінець останньої підсвітки, виконаної в одному з VISUALрежимів. Натомість у NORMALрежимі .може використовуватися спеціальний номер рядка , який просто означає поточний рядок . Отже, ви можете знайти / замінити лише поточний рядок на зразок цього:

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

Ще слід зазначити, що вставлення секунди :між діапазоном та командою знаходження / заміни не приносить шкоди, іншими словами, ці команди все одно працюватимуть:

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

1
> Приклад: замініть текст з рядків 6-10, 14-18, але не з 11-13. - Ваша відповідь не відповідає на це саме запитання, чи не так?
poige

27

Це можна зробити за допомогою двох послідовностей пошуку / заміни

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

Другий раз, коли вам потрібно скоригуватись - це діапазон, тому замість того, щоб усе це вводити, я б пригадав останню команду і відредагував просто діапазон


20

In vim, якщо ви плутаєте, які всі рядки будуть зачеплені, скористайтеся нижче

 :%s/foo/bar/gc  

Змініть кожен "foo" на "bar", але спочатку попросіть підтвердження. Натисніть "у" для так і "н" - ні. Не забудьте зекономити після цього

:wq

1
Насправді ви можете використовувати cпрапор крім того, щоб вказати діапазон, тому :6,10s/<search_string>/<replace_string>/cпрацює. cрозшифровується confirm. Я використовую cпрапор досить часто, щоб не випадково замінити слова там, де я не думав про те, що вони також існують.
Вольфсон

16

VI пошук і заміна прикладів команд

Скажімо, ви хочете знайти слово під назвою "foo" і замінити на "bar".

Перший [Esc]ключ натискання

Введіть: (двокрапка), після чого %s/foo/bar/натисніть клавішу [Enter]

:%s/foo/bar/


11
Ваша :%s/<search_string>/<replace_string>/gкоманда замінить усі події у всьому файлі. Не зовсім відповідь на питання, але корисна тим не менше :)
tanius

@tanius Насправді це була найбільш пряма відповідь на мою проблему. Ви можете розглянути питання про те, щоб змінити питання на "Знайти та замінити рядки в vim у" Вибраних "рядках"
Omid N

9

Нам не потрібно заважати вводити номер поточного рядка.

Якщо ви хочете змінити кожен fooна barпоточний рядок ( .) та два наступні рядки ( +2), просто зробіть:

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

Якщо ви хочете підтвердити, перш ніж будуть внесені зміни, замініть gна gc:

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

Ще одна приємна річ, яку я часто використовую - :.,$s/foo/bar/gcце пошук та заміна, починаючи з поточного рядка до кінця файлу.
Вольфсон

3

Шукайте та замінюйте

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

g => глобальний пошук

c => Попросіть спочатку підтвердження

i => Випадок нечутливий

Якщо ви хочете прямої заміни без підтвердження, використовуйте команду нижче

:%s/search/replace/g

Якщо ви хочете підтвердження для кожної заміни, виконайте команду нижче

:%s/search/replace/gc

Попросіть підтвердження спочатку, тут пошук буде нечутливим.

:%s/search/replace/gci

1

Вказати діапазон за допомогою візуального вибору нормально, але коли існують дуже прості операції лише через пару рядків, які може бути обраний оператором, найкраще було б застосувати ці команди як оператори.

Це, на жаль, неможливо зробити за допомогою стандартних команд vim. Ви можете зробити своєрідне вирішення за допомогою! (фільтр) оператора та будь-якого текстового об'єкта. Наприклад, щоб застосувати операцію до абзацу, ви можете:

!ip

Це слід читати як "Застосувати оператора! Всередині абзацу". Оператор фільтра запускає командний режим і автоматично вставляє діапазон рядків з наступним буквальним "!" яку ви можете видалити відразу після. Якщо ви застосовуєте це, до наступного пункту:

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

Результат після натискання "! Ap" буде таким:

:.,.+5

Як "." (точка) означає поточну лінію, діапазон між поточною лінією і 5 рядками після буде використовуватися для операції. Тепер ви можете додати команду-замінник так само, як і раніше.

Погана частина полягає в тому, що це не простіше, ніж вибирати текст для останнього, застосовуючи оператор. Хороша частина полягає в тому, що це може повторити введення діапазону для інших подібних текстових діапазонів (у цьому випадку абзаців) з дещо різним розміром. Тобто, якщо пізніше ви хочете вибрати абзац з більшим діапазоном '.' воля до цього право.

Крім того, якщо вам подобається ідея використання семантичних текстових об’єктів для вибору діапазону роботи, ви можете перевірити мій плагін EXtend.vim, який може зробити те саме, але простішим способом.


0

Щоб відповісти на це запитання:

:40,50s/foo/bar/g

замініть foo на бар в цих рядках між 40-м рядком і 50-м рядком (включно), коли виконувати цю команду, ви можете в даний час в будь-якому рядку.

:50,40s/foo/bar/g

також працює, vim попросить вас підтвердити, а потім зробить заміну для вас, як якщо б ви ввели першу команду.

:,50s/foo/bar/g

замініть foo на смугу в цих рядках між лінією, на якій ви зараз перебуваєте, і 50-й рядком (включно). (якщо ви знаходитесь у рядку ПІСЛЯ 50-го рядка vim знову попросить підтвердити)

Щоб зрозуміти різницю між vim та vrpper плагіном Eclipse:

Зауважте, що у варпері

:,50s/foo/bar/g команда НЕ працює.

:50,40s/foo/bar/g працюватиме, не вимагаючи підтвердження.

(Для версії Vrapper 0.74.0 або новішої версії).


-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

Припустимо, якщо ви хочете замінити вищенаведене на якусь іншу інформацію.

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

У цьому вищезазначене буде замінено на (sys.pkg.mpu.umc.kdk. ).


Я не впевнений, що це насправді відповідає на питання. З цього питання, можливо, людина, яка задає питання, вже знає, як використовувати %sдля зміни введення, але хоче знати, як це зробити "напів глобально" (тобто його специфікація - це рядки 6-10 та 14-18, але не на рядках 11- 13).
Брендон Бак

1
Також що таке "КОМАНД"? А ти страждаєш від синдрому схильної зубочистки .
Мартін Турноїй

Для того, щоб вилікувати цей синдром, ви можете використовувати інший символ в якості роздільника замість значення за замовчуванням /, наприклад !, @, _::%s_/sys/sim/source/gm/kg/jl/ls/owow/lsal_sys.pkg.mpu.umc.kdk_g
MortezaE
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.