Как я могу искать и заменить рекурсивно в каталоге в Vim?

Я узнал о команде замены Vim...

:%s/replaceme/replacement/gi

И vimgrep...

:vimgrep  /findme/gj  project/**/*.rb

Существует ли способ объединить их, чтобы сделать замену через все файлы в соответствии с каталогом?

40
задан Keith Pinson 14 December 2012 в 23:57
поделиться

4 ответа

Даже если я пользователь Vim, я вообще использую Найти и SED для такого рода вещи Отказ Синтаксис регулятора Regex для SED аналогичен VIM (они оба потомка ED , хотя и не идентичны. С GNU SED вы также можете использовать -I для установки (обычно SED , испускает модифицированную версию на STDOUT).

Например:

find project -name '*.rb' -type f -exec sed -i -e 's/regex/replacement/g' -- {} +

Шт. Piece:

  • Project = Поиск в «Проекте» дерева
  • -NAME '* .rb' = для вещей, чьи имена совпадают »* .rb «
  • -Type f = и являются регулярными файлами (не каталоги, трубы, симливки и т. Д.)
  • -Exec SED = RUN SED С помощью этих аргументов:
    • -I = с помощью установленных изменений
    • -E 'S / Regex / замена / G' = выполнить команду «подстановки» (которая практически идентична VIM : S , Но заметить отсутствие % - это значение по умолчанию в SED )
    • - = Конец флагов, имена файлов начинаются здесь
    • {} = Это рассказывает Найти , что найденные имена файлов, которые она найдена, должна быть помещена на командную строку SED здесь
    • + = это говорит Найти , что - EXEC Действие завершено, и мы хотим группировать аргументы в немногих вызовов , как это возможно (в целом более эффективно, чем запустить его один раз на имя файла). Чтобы запустить его один раз на имя файла, вы можете использовать \; вместо + .

Это общее решение с GNU SED и Найти . Это может быть сокращено немного в особых случаях. Например, если вы знаете, что ваша картина имени не будет соответствовать никаких каталогов, которые вы можете оставить -Type F . Если вы знаете, что ни один из ваших файлов не начинается с - , вы можете оставить - . Вот ответ, который я разместил в другой вопрос с более подробной информацией о прохождении файлов, найденных с Найти на другие команды.

65
ответ дан 27 November 2019 в 01:05
поделиться

Один из способов было бы открыть все файлы, которые вы хотите запустить замену (или любой команды), и запустить : BUFDO , который будет работать на всех открытых буферах.

5
ответ дан 27 November 2019 в 01:05
поделиться

Там есть плагин, который стремится сделать только что: Vimgrep заменить .

О, подождите ... Есть другие: Global Breake , EasyGrep .

Для решения плагина, возможно, ARGDO поможет, если вы можете получить вывод Vimgrep в списке аргументов (который можно установить с args ), но я не могу понять детали. Я был бы счастлив, если кто-то взял на себя идею и улучшил его ... Так вот это.

Основная идея первого плагина (я думаю, что другие тоже ...) - это использовать Vimgrep сначала, затем цикл через спички с : cnex и применить Команда замены на каждой строке. Функция для достижения этого может быть достаточно маленькой, чтобы положить его в .vimrc. (Может быть, вы можете поднять один из источников плагинов?)

(я полагаю, что Hgimenez может быть включен в решение, но, вероятно, это, вероятно, будет зависеть от количества файлов, которые будут обработаны ... быть в порядке, независимо от.)

4
ответ дан 27 November 2019 в 01:05
поделиться

Вы можете запустить Vimgrep, затем запишите макрос, который отправляется в каждую строку в выходе Vimgrep и делает замену, что-то вроде этого: (не введите # комментарии!)

:set autowrite                  #automatically save the file when we change buffers
:vimgrep /pattern/ ./**/files  
qa                              #start recording macro in register a
:s/pattern/replace/g            #replace on the current line
:cnext                          #go to next matching line
q                               #stop recording
10000@a                          #repeat the macro 10000 times, or until stopped by 
                                #an "error" such as reaching the end of the list
:set noautowrite

Не тестировал это, поэтому может потребоваться небольшая настройка - проверьте его на некоторых файлах, которые вы не возражаете в том, чтобы войти первым.

Преимущество этого превышения SED заключается в том, что VIM Regex более мощными, и вы можете добавить опцию C для: s, чтобы проверить каждую замену.

Редактировать : Я изменил свой оригинальный пост, так как это было неправильно. Я использовал: 1vimgrep, чтобы найти первый матч в каждом файле, но я неправильно пропускает документы - он только находит один матч во всех файлах.

7
ответ дан 27 November 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: