Интерактивный поиск и замена во всех файлах, включая файлы в подкаталогах, использующих Vim - PullRequest
0 голосов
/ 20 апреля 2019

Я хотел бы использовать Vim, чтобы найти определенную строку и заменить ее другой. Для каждой замены следует запрашивать подтверждение, аналогичное тому, что %s/foo/replace/gc делает для одного файла в Vim.

Что я пробовал?

  1. sed: интерактивные замены не выполняются.
  2. Один из комментариев в следующей этой ссылке предлагает vim -esnc '%s/foo/bar/g|:wq' file.txt. Я попробовал vim -esnc '%s/foo/bar/gc|:wq' file.txt (использовал gc вместо g ). Теперь терминал зависает.
  3. Emacs xah-find-replace пакет . К сожалению, он не делал интерактивные замены, как обещано в ссылке.

Ответы [ 3 ]

2 голосов
/ 20 апреля 2019

Комбинация :argdo с командой замены была бы рекомендуемым способом сделать это.

Вы можете заполнить аргументы, открыв все файлы vim *.txt или заполнив их вручную после открытия vim с помощью команды:

:args `find . -type f -name '*.txt'`

Теперь установите скрытым, используя команду:

:set hidden

это необходимо, чтобы вам не предлагалось сохранять файл при переключении с одного буфера на другой. Для получения дополнительной информации см. :h hidden.

Теперь используйте команду замены, как вы привыкли, с префиксом argdo, чтобы выполнить это для каждого файла в списке аргументов

:silent argdo %s/pattern/replace/gec

silent является необязательным и просто отключает отчеты. Флаг e должен прекратить сообщать об ошибке в найденных совпадениях в некоторых буферах

Теперь после замены вы можете записать изменения, используя следующую команду

:argdo update

Это будет записывать буферы, которые были изменены только.

2 голосов
/ 20 апреля 2019

Если вы ищете интерактивный режим замены, это проще сделать с помощью vim.

vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' FILENAME

Застрявший терминал в вашем случае вызван передачей команды сохранения в строку замены,так как он не позволяет интерактивному режиму войти в действие.И это не застрявший терминал, если вы наберете «да» и нажмете клавишу ввода, он все равно покажет ожидаемый результат.

Если задействовано несколько файлов, которые распределены по нескольким подкаталогам, используйте команду find с forПоможет цикл как указано ниже:

for FILENAME in `find DIRECTORYPATH -type f -name *.txt` 
do 
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' $FILENAME
done
1 голос
/ 20 апреля 2019

В bash включите двойную звездочку, чтобы вывести список всех файлов во всех подкаталогах:

shopt -s globstar

Теперь запустите vim один раз со всеми файлами и выполните команду замены для всех файлов, затем сохраните и выйдите:

vim -c 'set nomore' -c 'argdo %s/foo/bar/gc' -c xa **/*.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...