Команда :global - оружие массового редактирования

Рейтинг: 62.1% · 15 голосов
Исчерпывающий курс по Vim и Neovim: модальное редактирование и грамматика (операторы, движения, текстовые объекты, точка-команда), регистры, метки, макросы, поиск и :substitute, :global, буферы/окна/quickfix, визуальный режим, конфигурация на Lua, маппинги, плагины (lazy.nvim), LSP, автодополнение (blink.cmp), Treesitter, fuzzy-поиск, Git, эргономика и антипаттерны. 34 главы, актуально на 2026 (Vim 9.1, Neovim 0.11/0.12).
Ответить
Аватара пользователя
Roman_Vim
Сообщения: 34
Зарегистрирован: 11 май 2026, 05:31

Команда :global - оружие массового редактирования

Сообщение Roman_Vim »

Оглавление курса (34)
  1. Философия Vim: модальное редактирование и почему это актуально в 2026
  2. Установка и выживание: первый запуск, режимы, как выйти
  3. Перемещение по тексту: движения как основа эффективности
  4. Базовое редактирование: вставка, удаление, копирование
  5. Грамматика Vim: операторы + движения = команды
  6. Текстовые объекты: оперируем структурой, а не символами
  7. Точка-команда и повторяемость: "один штрих, чтобы повторить"
  8. Регистры: продвинутая работа с буфером обмена
  9. Метки и прыжки: навигация по истории перемещений
  10. Поиск: /, ?, *, # и магия паттернов
  11. Замена :substitute и регулярные выражения Vim
  12. Команда :global - оружие массового редактирования (вы здесь)
  13. Буферы, окна и вкладки: организация рабочего пространства
  14. Quickfix и location list: пакетная работа по всему проекту
  15. Навигация по файлам: netrw, fuzzy-поиск и проекты
  16. Макросы: автоматизация повторяющихся правок
  17. Визуальный режим и блочное редактирование
  18. Трюки режима вставки
  19. Свёртки, автодополнение и аббревиатуры (встроенные)
  20. Конфигурация с нуля: init.lua и разумные дефолты 2026
  21. Маппинги: leader, which-key и здравые привычки
  22. Скриптинг: основы Vimscript и Lua для Neovim
  23. Менеджеры плагинов: lazy.nvim и lazy-loading
  24. Neovim в 2026: чем отличается и почему выбирают
  25. LSP в Neovim: умные возможности языка
  26. Автодополнение 2026: blink.cmp против nvim-cmp
  27. Treesitter: точная подсветка и структурное редактирование
  28. Fuzzy-поиск: Telescope, fzf-lua и snacks.picker
  29. Git внутри редактора: fugitive, gitsigns и lazygit
  30. Дистрибутивы, отладка и терминал: быстрый старт и интеграции
  31. Vim повсюду: IDE, браузер и shell
  32. Эргономика и антипаттерны: как не навредить себе и не застрять
  33. Рабочие рецепты, тренажёры и план обучения
  34. Шпаргалка-справочник: все ключевые команды одним списком
В предыдущих главах вы научились искать паттерны (глава 10) и заменять текст с помощью :substitute и регулярных выражений (глава 11). :substitute отлично справляется с трансформацией содержимого строк. Но что делать, когда вам нужно не заменить текст внутри строк, а выполнить над целыми строками произвольное действие - удалить их, переместить, продублировать, прогнать по ним макрос или нормальную команду? Здесь на сцену выходит :global - пожалуй, самая недооценённая и при этом самая мощная команда в арсенале Vim.

:global - это не "ещё один поиск". Это движок пакетной обработки: "найди все строки, подходящие под паттерн, и выполни над каждой вот эту Ex-команду". Освоив её, вы будете решать за одно нажатие Enter задачи, на которые в обычном редакторе ушли бы десятки кликов или отдельный скрипт. Эта глава - про то, как :global устроена, почему она так работает, и какие рецепты делают её незаменимой.

Зачем это нужно

Представьте типичные задачи:
  • Удалить из лог-файла все строки, содержащие DEBUG.
  • Оставить только строки с ERROR, выбросив всё остальное.
  • Собрать все строки с TODO в конец файла.
  • Добавить точку с запятой в конец каждой строки, объявляющей переменную.
  • Пронумеровать или закомментировать определённые строки.
  • Отсортировать или перевернуть блок строк без внешних утилит.
Каждую из них :global решает одной командой. Это декларативный подход: вы описываете что (паттерн) и что с этим делать (команда), а Vim сам проходит по буферу. В отличие от макроса (глава 16), который выполняется "пока не упрётся в ошибку", :global работает по чёткому критерию совпадения и предсказуема.

Как устроена :global: анатомия команды

Полный синтаксис:

Код: Выделить всё

:[range]g/{pattern}/{cmd}
  • [range] - диапазон строк. По умолчанию - весь буфер (%), что отличает :global от :substitute, где дефолтный диапазон - только текущая строка.
  • g - сокращение от :global.
  • /{pattern}/ - паттерн поиска (те же регулярные выражения, что в главе 11; разделителем может быть не только /).
  • {cmd} - любая Ex-команда, которая выполнится на каждой совпавшей строке. Если команду опустить, по умолчанию выполняется :print (вывод строки).
Двухфазная модель - ключ к пониманию

Самое важное, что нужно усвоить: :global работает в два прохода, и понимание этого избавляет от множества загадочных багов.
  1. Первый проход (mark): Vim сканирует весь диапазон и помечает внутренней меткой каждую строку, совпавшую с паттерном. Никакие изменения ещё не вносятся.
  2. Второй проход (execute): Vim проходит по помеченным строкам и выполняет {cmd} на каждой.
Почему это критично? Потому что команды вроде :d (удаление) сдвигают номера строк. Если бы Vim вычислял совпадения "на лету" во время удаления, нумерация поехала бы и часть строк он бы пропустил. Благодаря предварительной пометке :g/pat/d корректно удаляет все совпадения, даже идущие подряд. Vim умно отслеживает помеченные строки даже после сдвигов.
Тонкость с многострочными паттернами. Если паттерн содержит \n (то есть может растягиваться на несколько строк), Vim при пометке учитывает только начало совпадения - помечается лишь та строка, где совпадение начинается. Это частый источник сюрпризов: команда выполнится один раз на стартовой строке, а не "на всём блоке". Для работы с блоками надёжнее задавать диапазон внутри :g (см. раздел "Диапазоны внутри :global"), а не закладываться на \n в самом паттерне.
:vglobal (он же :g!) - инверсия

Близнец :global - :vglobal (:v удобно запоминать как inVerse, хотя это лишь мнемоника, а не официальная этимология - в документации Vim :v/:vglobal определяется просто как синоним :g!), он же :g!. Он выполняет команду на всех строках, которые не совпали с паттерном:

Код: Выделить всё

:v/{pattern}/{cmd}
:g!/{pattern}/{cmd}
Мнемоника: :g - "делай с совпавшими", :v - "делай со всеми, кроме совпавших". Классический пример - :v/ERROR/d оставляет в файле только строки с ERROR, удаляя весь шум.

Таблица базовых команд

Код: Выделить всё

Команда                |  Что делает
-----------------------+----------------------------------------------------------------
:g/pat/                |  Вывести (:print) все строки с pat
:g/pat/d               |  Удалить все строки с pat
:v/pat/d               |  Удалить все строки без pat (оставить только совпавшие)
:g!/pat/d              |  То же, что :v/pat/d
:g/pat/m$              |  Переместить все строки с pat в конец буфера
:g/pat/m0              |  Переместить все строки с pat в начало (порядок инвертируется)
:g/pat/t.              |  Продублировать (скопировать под себя) каждую строку с pat
:g/pat/normal! {keys}  |  Выполнить нормальные команды {keys} на каждой совпавшей строке
:g/pat/s/a/b/g         |  Запустить :substitute только на совпавших строках
:g/pat/normal! @q      |  Прогнать макрос из регистра q по совпавшим строкам
:g/^/m0                |  Перевернуть весь буфер (реверс строк)
:[range]g/pat/cmd      |  Ограничить действие диапазоном вместо всего буфера
В реальном коде у :normal используйте форму с восклицательным знаком - :g/pat/normal! {keys} - чтобы игнорировать пользовательские маппинги (подробнее ниже и в "Лучших практиках").
Команды над строками: удаление, перемещение, копирование

Внутри :global чаще всего используют четыре Ex-команды редактирования строк. Запомните их - это рабочие лошадки.

Код: Выделить всё

Ex-команда           |  Полное имя  |  Действие
---------------------+--------------+----------------------------------------
:d                   |  :delete     |  Удалить строку
:m {addr}            |  :move       |  Переместить строку после адреса {addr}
:t {addr} (или :co)  |  :copy       |  Скопировать строку после адреса {addr}
:p                   |  :print      |  Вывести строку (дефолт)
Адреса для :m и :t:
  • $ - последняя строка буфера.
  • 0 - "перед первой строкой" (виртуальная нулевая позиция).
  • . - текущая строка (та, на которой сейчас выполняется команда внутри :g).
Удаление: :g/pat/d и :v/pat/d

Код: Выделить всё

Было:                          :g/^#/d            Стало:
  code line 1                  (удалить                code line 1
  # comment                     все строки-            another line
  another line                  комментарии)
  # another comment
Best-practice из :help :global: удаляйте в чёрную дыру. Каждое :d без аргумента кладёт удалённую строку в безымянный регистр " (и сдвигает нумерованные регистры). При массовом :g/pat/d это бессмысленно затирает буфер обмена и чуть тормозит. Удаление в чёрную дыру _ ничего не сохраняет, не трогает ваши регистры и работает быстрее:
`
:g/pat/d _
`
Это официальный пример из документации - берите его привычкой для любых разрушительных :g, после которых вы хотите сохранить содержимое регистров (например, чтобы потом сделать "0p).
А инверсия оставляет только нужное:

Код: Выделить всё

Было:                          :v/ERROR/d         Стало:
  INFO: starting               (удалить               ERROR: disk full
  ERROR: disk full              всё, кроме             ERROR: timeout
  WARN: low memory              ERROR)
  ERROR: timeout
  INFO: done
Перемещение: :g/pat/m$

Собрать все совпадающие строки в конец файла, сохранив их относительный порядок:

Код: Выделить всё

Было:                          :g/TODO/m$         Стало:
  TODO fix parser                                     impl done
  impl done                                           more code
  TODO add tests                                      TODO fix parser
  more code                                           TODO add tests
Почему порядок сохраняется? Потому что :g обрабатывает строки сверху вниз, и каждая следующая TODO-строка перемещается в конец после предыдущей. Если бы вы хотели обратный порядок, использовали бы m0 (каждая новая совпавшая строка встаёт перед всеми ранее перемещёнными).

Копирование: :g/pat/t.

:t. (copy to "здесь") дублирует каждую совпавшую строку прямо под ней:

Код: Выделить всё

Было:                          :g/^name:/t.       Стало:
  name: Alice                                         name: Alice
  age: 30                                             name: Alice
                                                      age: 30
Адрес . - это "текущая строка" внутри прохода :g, поэтому копия ложится сразу после оригинала. Сравните с :g/pat/t$ - все копии уйдут в конец файла.

Сортировка и реверс через :g/^/m0

Один из самых элегантных трюков: перевернуть порядок строк во всём буфере (или диапазоне).

Код: Выделить всё

:g/^/m0
Разберём, почему это работает. Паттерн ^ (начало строки) совпадает с каждой строкой. Команда m0 перемещает строку в самое начало (после позиции 0). Vim идёт сверху вниз: первая строка уходит в начало (остаётся на месте), вторая встаёт перед ней, третья - перед второй... В итоге порядок инвертируется.

Код: Выделить всё

Было:           :g/^/m0      Стало:
  one                           four
  two                           three
  three                         two
  four                          one
Для реверса только части файла задайте диапазон: :10,20g/^/m0.
Важно: для сортировки по алфавиту не нужна :global - в Vim есть штатная команда :sort (и :sort! для обратного порядка, :sort u для удаления дублей, :sort n для числовой сортировки). :g/^/m0 - это именно реверс, а не сортировка. Не путайте.
Нормальные команды над совпадениями: :g/pat/normal

Это самая мощная связка. :normal {keys} выполняет последовательность клавиш нормального режима так, будто вы их набрали. В сочетании с :g вы получаете "выполни эти нажатия на каждой подходящей строке".

Код: Выделить всё

:g/foo/normal A;
A входит в режим вставки в конце строки, ; дописывает точку с запятой, а Vim автоматически возвращается в нормальный режим в конце каждой итерации :normal.

Код: Выделить всё

Было:                          :g/^let/normal A;   Стало:
  let x = 1                                            let x = 1;
  print(x)                                             print(x)
  let y = 2                                            let y = 2;
Несколько практических нюансов :normal:
  • Esc автоматически не нужен в конце - :normal сам выходит из режима вставки после выполнения. Но если вам нужен <Esc> в середине последовательности, его придётся вставить буквально. В командной строке это делается через Ctrl-V Esc (отобразится как ^[), либо используйте :execute "normal! A;\<Esc>jj".
  • Используйте :normal! (с восклицательным знаком), чтобы игнорировать пользовательские маппинги - иначе ваши кастомные ремапы клавиш могут испортить выполнение. Внутри :g это особенно важно для надёжности.
  • Курсор на каждой итерации стоит в первом столбце (column 1) совпавшей строки - то есть на самом первом символе, включая ведущие пробелы/табы (а не на первой непробельной позиции). Это важно помнить рядом с column-sensitive командами вроде I/A: :g/./normal! x на строке с ведущим отступом удалит именно ведущий пробел/таб. Если нужно встать на первый непробельный символ, добавьте ^ в начало последовательности, например :g/pat/normal! ^....
Прогон макроса по совпадениям

Записанный макрос (глава 16) можно запустить только на нужных строках:

Код: Выделить всё

:g/pattern/normal @q
Это часто чище и предсказуемее рекурсивного макроса: вы декларативно задаёте, на каких строках работать, вместо того чтобы крутить макрос "до первой ошибки". Применяйте, когда число элементов заранее неизвестно, но критерий совпадения чёткий.

Комбинация с :substitute

Внутри :g можно вызывать :s, и это открывает интересную возможность: делать замену только в строках, удовлетворяющих одному паттерну, по другому паттерну.

Код: Выделить всё

:g/pattern_A/s/pattern_B/replacement/g
Читается так: "на каждой строке, где есть pattern_A, заменить все pattern_B на replacement". Это контекстная замена, недостижимая одним :s.

Код: Выделить всё

Было:                          :g/^config/s/=/: /   Стало:
  config host=localhost                                config host: localhost
  data host=remote                                     data host=remote
  config port=8080                                     config port: 8080
Здесь знак = поменялся на : только в строках, начинающихся с config.

Инверсия тоже работает - :v/pattern_A/s/.../.../ заменит во всех строках, кроме содержащих pattern_A.
Тонкость: :g задаёт last search pattern. По документации :help :global команда :g устанавливает не только последний паттерн поиска, но и "последний использованный паттерн подстановки". Поэтому, если паттерн для :s совпадает с паттерном :g, во вложенном :s его можно опустить - пустой паттерн // подставит паттерн от :g:
`
:g/TODO/s//DONE/g
`
Здесь s//DONE/g заменяет именно TODO (паттерн взят из :g/TODO/) на DONE. Лаконично, но именно из-за этой "магии пустого паттерна" бывает неожиданно - держите в голове, что :g перетирает last search/substitute pattern.
Заметьте: ту же задачу иногда решает один :s с хитрым паттерном через \zs/\ze (см. главу 11), но :g + :s обычно читается яснее, когда "строка-условие" и "текст-замена" - это две разные вещи.
Мощные рецепты

Соберём арсенал реальных однострочников.

Удалить все пустые строки:

Код: Выделить всё

:g/^$/d
(^$ - строка, где начало сразу переходит в конец, то есть пустая.)

Схлопнуть несколько подряд идущих пустых строк в одну. Сначала удалить пустые, у которых следующая тоже пустая:

Код: Выделить всё

:g/^\s*$/,/\S/-j
(Продвинутый рецепт - использует диапазон внутри :g; см. ниже про диапазоны.)

Пронумеровать совпавшие строки (через внешнюю команду или :normal):

Код: Выделить всё

:g/^/normal! I- 
(Добавит маркер - в начало каждой строки списка. Напомним: курсор внутри :normal стоит в column 1, поэтому I вставляет ровно перед первым символом строки.)

Перенести все строки import в начало файла, сохранив порядок:

Код: Выделить всё

:g/^import/m0
Внимание: m0 инвертирует порядок! Чтобы сохранить исходный порядок импортов, используйте трюк с промежуточным сбором или примите инверсию осознанно. Для сохранения порядка надёжнее: переместить в конец, потом блок в начало, либо :g/^import/normal "Idd с последующей вставкой - но на практике чаще достаточно m0 + отдельная :sort.

Удалить строки между парой маркеров (диапазон внутри :g):

Код: Выделить всё

:g/BEGIN/,/END/d
Удалит каждый блок от строки с BEGIN до ближайшей END включительно.

Подсчитать количество совпадений без изменений - самый безопасный "dry run":

Код: Выделить всё

:g/pattern/p
В Neovim с включённым inccommand (глава 11) у :s есть живой предпросмотр, но у :g его нет - поэтому :g/pat/p или :g/pat/# (с номерами строк) остаётся главным способом "посмотреть, что зацепит", прежде чем делать :g/pat/d.

Скопировать все совпавшие строки в регистр (накопление через append-регистр):

Код: Выделить всё

:g/ERROR/y A
:yank A дописывает (append) каждую совпавшую строку в регистр a (заглавная буква = append). После этого "ap вставит все собранные строки. Подробнее о регистрах - глава 8.

Условие "совпало A, но НЕ B" - вложенный :g/:v. В качестве {cmd} для :g может выступать другой :g или :v. Это документированная техника фильтрации по двум критериям сразу. Удалить строки, где есть foo, но нет bar:

Код: Выделить всё

:g/foo/v/bar/d
Читается как "среди строк с foo возьми те, что не содержат bar, и выполни на них d". Симметрично :g/foo/g/bar/d сработает на строках, где есть и foo, и bar. Внутренний :g/:v во втором проходе применяется к той единственной строке, на которой стоит внешний :g, - фактически это "фильтр поверх фильтра".

Диапазоны внутри :global

Внутри второго прохода :g адрес . (текущая строка) указывает на совпавшую строку. Это позволяет строить относительные диапазоны:

Код: Выделить всё

:g/pat/.,+2d        " удалить совпавшую строку и две следующие
:g/pat/.+1d         " удалить строку ПОСЛЕ каждого совпадения
:g/start/,/end/d    " удалить блок от совпадения до ближайшего 'end'
Это превращает :g в инструмент работы с блоками, а не только с отдельными строками - мощно, но требует аккуратности (легко зацепить лишнее при перекрывающихся блоках).

Лучшие практики 2026
  • Фиксируйте магический режим паттерна. Как и в :s, для нетривиальных паттернов начинайте с \v (very magic) - тогда (), +, ?, |, {} работают без бэкслешей: :g/\v^(foo|bar)/d. В скриптах (Vimscript/Vim9script) обязательно явно задавайте режим (\v/\m/\M/\V), чтобы команда не зависела от пользовательской опции 'magic' и не сломалась на чужой машине. Подробнее о магических режимах - глава 11.
  • Всегда делайте "dry run". Перед разрушительной :g/pat/d запустите :g/pat/p или :g/pat/#, чтобы увидеть список затрагиваемых строк. Дёшево и спасает от катастроф.
  • Используйте :normal!, а не :normal. Восклицательный знак игнорирует ваши маппинги - поведение становится воспроизводимым независимо от конфига. Для надёжных скриптов это правило по умолчанию.
  • Ускоряйте тяжёлые :g на больших файлах. Главный тормоз :g по огромному буферу - это перерисовка экрана на каждой итерации и срабатывание автокоманд. Оберните вызов, чтобы погасить лишнюю работу: :silent подавляет вывод, :noautocmd отключает автокоманды (актуально, когда {cmd} дёргает обработчики событий), а опция 'lazyredraw' (set lazyredraw) откладывает перерисовку до конца. Например: :noautocmd silent g/pat/normal! .... На файлах в сотни тысяч строк это даёт заметный выигрыш; на коротких - разницы нет, не усложняйте.
  • Знайте границу между :g и quickfix-инструментами. :global работает в пределах одного буфера. Для пакетных правок по многим файлам проекта используйте :grep/ripgrep + :cfdo (глава 14) или современный grug-far.nvim - там есть редактируемый предпросмотр результатов и синк обратно в файлы. :g - это "массовое редактирование внутри файла", quickfix - "по всему проекту".
  • Для замены в одном файле с визуальным контролем рассмотрите паттерн * + cgn + . (глава 11): он позволяет выборочно применять правку к каждому следующему совпадению. :g хорош, когда правка должна примениться ко всем совпадениям без раздумий.
  • :g доступна в "настоящем" Vim/Neovim, но не везде. В режимах эмуляции Vim внутри IDE (IdeaVim, VSCodeVim) :global и :normal часто не поддерживаются или урезаны. Полноценная семантика - в vscode-neovim, который встраивает реальный Neovim. Если вы живёте в IDE, не рассчитывайте на :g слепо (см. главу 31).
Частые ошибки
  • Забытый диапазон. Помните: дефолт :g - весь буфер. Если хотели обработать только выделение, начните с него: :'<,'>g/pat/d. Иначе удалите по всему файлу.
  • Разрушительная :g/pat/d без предпросмотра. Один неверный паттерн - и пол-файла нет. Сначала p/#, потом d. И помните про u (undo) - :g откатывается одним u целиком, это её приятное свойство.
  • <Esc> в :normal не вставился буквально. Если последовательность требует выхода из вставки в середине, нельзя просто напечатать "Esc" - нужно Ctrl-V Esc (отобразится ^[) или, надёжнее, :execute "normal! ...\<Esc>...". Обычный набор Esc просто оборвёт ввод командной строки.
  • Путаница m0 и сохранения порядка. :g/pat/m0 инвертирует порядок собранных строк. Если нужен исходный порядок - собирайте в конец (m$) или используйте :sort после.
  • Путаница :t. и :t$. . дублирует строку на месте, $ - отправляет копию в конец файла. Перепутаете адрес - получите не то.
  • Ожидание inccommand-предпросмотра. Живой предпросмотр в Neovim есть у :substitute, но не у :global. Не полагайтесь на него - делайте явный dry run.
  • :normal без ! ломается на чужих маппингах. Если в конфиге переопределены A, dd и прочие, :g/pat/normal A; поведёт себя странно. Берите :normal!.
Упражнения
  1. Чистка логов. Возьмите любой лог-файл (или создайте его с строками INFO, WARN, ERROR, DEBUG). Одной командой оставьте только строки с ERROR. Затем второй командой удалите все строки DEBUG, не трогая остальные. Какую команду вы использовали для "оставить только" и почему :v удобнее, чем сложный :g?
  1. Сборщик TODO. В файле с кодом разбросаны строки с TODO. Соберите их все в конец файла, сохранив относительный порядок. Затем продублируйте каждую TODO-строку прямо под ней. Подсказка: m$ и t..
  1. Реверс и сортировка. Создайте список из 6 строк. Переверните его одной командой :g. Затем верните как было, но уже отсортировав по алфавиту (вспомните, что для сортировки :g не нужна). Объясните, почему :g/^/m0 инвертирует порядок.
  1. Массовое дописывание. В файле есть строки, начинающиеся с let (или var), и обычные строки. Допишите ; в конец только строк с объявлениями, используя :g + :normal. Затем сделайте то же, но через :g + :s (без :normal). Сравните читаемость.
  1. Контекстная замена. В конфиг-файле есть строки config key=value и data key=value. Замените = на : только в строках, начинающихся с config, не трогая data-строки. Решите это связкой :g/.../s/.../.../.
  1. Блочное удаление. В файле есть несколько блоков вида BEGIN ... END. Удалите все такие блоки целиком одной командой, используя диапазон внутри :g (:g/BEGIN/,/END/d). Проверьте на dry run, что зацепится именно то, что нужно.
Главное из главы
  • :[range]g/pat/cmd выполняет Ex-команду cmd на каждой строке, совпавшей с pat; дефолтный диапазон - весь буфер.
  • :v/pat/cmd (он же :g!) - инверсия: команда на всех строках, кроме совпавших. :v/pat/d = "оставить только совпавшие".
  • :g работает в два прохода (сначала помечает строки, потом выполняет команду) - поэтому :g/pat/d корректно удаляет даже соседние совпадения.
  • Рабочие лошадки внутри :g: :d (удалить), :m{addr} (переместить), :t{addr} (копировать), :p (вывести). Адреса: $ - конец, 0 - начало, . - текущая строка.
  • :g/^/m0 инвертирует порядок строк; для сортировки есть отдельная :sort.
  • :g/pat/normal! {keys} прогоняет нажатия нормального режима по совпадениям; :g/pat/normal! @q - макрос по совпадениям. Используйте normal! для надёжности.
  • :g/A/s/B/C/g - контекстная замена: меняем B на C только в строках с A.
  • Перед :g/pat/d делайте dry run через :g/pat/p; у :g, в отличие от :s, нет inccommand-предпросмотра.
  • :g - это массовое редактирование в одном буфере. Для многофайловых правок переходите к quickfix и :cfdo (глава 14).
👍1 ❤️3 🔥2 😄 🤔1
✔ Лучший ответ сформирован автоматически — elasticops
Roman_Vim писал(а):Удаление в чёрную дыру _ ничего не сохраняет, не трогает ваши регистры и работает быстрее вот это золото, всегда забивал безымянный регистр массовым удалением а потом удивлялся что :p вставляет не то. теперь только :g/pat/d _
Перейти к ответу →
Аватара пользователя
henery
Сообщения: 2
Зарегистрирован: 24 май 2026, 15:41

Re: Команда :global - оружие массового редактирования

Сообщение henery »

вот про два прохода это прям откровение. раньше думал что :g/pat/d пропускает соседние строки если они подряд идут, а оно сначала помечает все, потом удаляет. теперь понятно почему ничего не едет
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
jonlong
Сообщения: 1
Зарегистрирован: 06 июн 2026, 07:10

Re: Команда :global - оружие массового редактирования

Сообщение jonlong »

:v/ERROR/d для чистки логов вообще топ, выкинул весь шум одной строкой. до этого пытался регуляркой через :s сделать, мучался
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
jsepulveda
Сообщения: 1
Зарегистрирован: 04 июн 2026, 20:06

Re: Команда :global - оружие массового редактирования

Сообщение jsepulveda »

а у меня :g/foo/normal A; почему то ведет себя странно на некоторых строках, минут двадцать тупил пока не дошло что у меня A переопределена в конфиге. поставил normal! с воклицательным и все заработало. в уроке же написано, читать надо внимательнее
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
ssfever
Сообщения: 1
Зарегистрирован: 01 июн 2026, 13:21

Re: Команда :global - оружие массового редактирования

Сообщение ssfever »

:g/^/m0 для реверса это красиво конечно. не сразу врубился почему инвертит а не сортирует, пока не перечитал что каждая следующая встает ПЕРЕД уже перемещенными
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
elasticops
Сообщения: 1
Зарегистрирован: 07 июн 2026, 12:37

Re: Команда :global - оружие массового редактирования

Сообщение elasticops »

✔ Лучший ответ — сформирован автоматически
Roman_Vim писал(а):Удаление в чёрную дыру _ ничего не сохраняет, не трогает ваши регистры и работает быстрее
вот это золото, всегда забивал безымянный регистр массовым удалением а потом удивлялся что :p вставляет не то. теперь только :g/pat/d _
👍2 ❤️1 🔥 😄 🤔1
Аватара пользователя
DenoAndy
Сообщения: 1
Зарегистрирован: 15 май 2026, 22:07

Re: Команда :global - оружие массового редактирования

Сообщение DenoAndy »

делюсь лайфхаком: повесил себе :g/TODO/m$ собирать все туду в конец перед коммитом, удобно глянуть что недоделано. а еще :g/pat/p как dry run перед удалением спасает, у :g же предпросмотра нет в отличие от :s
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
kotlin_lord
Сообщения: 1
Зарегистрирован: 14 май 2026, 16:12

Re: Команда :global - оружие массового редактирования

Сообщение kotlin_lord »

вопрос про многострочные паттерны - если в паттерне \n, помечается только строка где совпадение начинается? то есть :normal отработает один раз а не на всем блоке? правильно понял или туплю
👍1 ❤️ 🔥 😄 🤔2
Ответить
← Предыдущая глава
Замена :substitute и регулярные выражения Vim
Следующая глава →
Буферы, окна и вкладки: организация рабочего пространства

Все главы курса «Vim и Neovim: модальное редактирование от основ до современного Neovim»

Поделиться темой: ✈ Telegram VK

Вернуться в «Vim и Neovim: модальное редактирование от основ до Neovim 2026»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость