Pull to refresh

Vim. Одновременное изменение нескольких файлов. Развернутый пример с комментариями

Reading time2 min
Views5.9K
Бывают ситуации когда нужно выполнить какую-то последовательность действий одновременно в нескольких файлах. Конечно, для этого можно использовать разные инструменты (навскидку: bash + sed/awk, python/perl, ...) — какие-то будут менее приспособлены для выполнения поставленной задачи, какие-то — более. Сейчас мы рассмотрим пример решения одной такой простой задачи средствами редактора Vim.

Рассмотрим простой пример: вставка строки в начало каждого файла.

По ходу выполнения этой простой задачи могут возникнуть некоторые нюансы использования Vim, знание которых может быть нужным и полезным в работе с этим замечательным редактором. Одновременно этот пример даст возможность новичкам закрепить в своей практике использование регистров и макросов Vim.

Итак, приступим:

1. Открываем в редакторе все файлы в которых нужно сделать изменения:

$ vim -o file1.txt file2.txt file3.txt

Опция -o дает возможность открыть каждый файл в отдельном окне. Запуск с данной опцией в примере сделан не только для наглядности (все изменения будут видны сразу), но и исходя из еще одного момента о котором будет сказано ниже.

2. Записываем последовательность действий которую необходимо проделать над файлами в макрос:

qm1GOПервая строка<ESC>qu

qm — начало записи макроса в регистр m
1G — переход на первую строку файла
O (большая латинская буква O) — вставка строки перед текущей строкой с переходом в режим редактирования
Первая строка — содержание первой строки
<ESC> — выход из режима редактирования
q — окончание записи макроса
u — отмена изменений в текущем окне во избежания дублирования сделанных изменений

3. Запуск макроса m во всех окнах:

:windo normal @m

windo — команда запуска команды vim во всех окнах
normal — команда запуска команды нормального режима vim из командной строки, то есть две команды запуска макроса эквиваленты:
@m
:normal @m

Если бы мы просто сделали так:
:windo @m
то мы бы получили сообщение об ошибке «Это не команда редактора»
по сути мы бы в каждом окне выполнили такое действие:
: @m
что является неверным, поскольку мы запускаем команду нормального режима в командной строке. В итоге мы можем получить либо сообщение об ошибке либо непредсказуемые действия редактора.

Есть команды, аналогичные :windo:
:argdo
:tabdo
:bufdo

Первая команда — :argdo. Мощная команда, которая позволяет выполнить команду в списке файлов заданном как именованный аргумент. Здесь мы ее рассматривать не будем.
Вторая команда — :tabdo. Полностью аналогична нашей windo, но проделывает всю работы над всеми открытыми вкладками. Тут есть один момент о котором стоит упомянуть: в каждой вкладке может быть несколько окон. Так вот, изменения будут только в текущем окне каждой вкладки!
Ну инаконец третья команда — :bufdo. Выполняет команду над всеми буферами. Но при ее использовании есть один нюанс. Сама команда bufdo выполнится только в текущем буфере и завершится с ошибкой если «полезная» команда (та, которую запускает bufdo и которая должна выполниться в каждом буфере) изменяет текст.

Например так:
:bufdo normal G
выполнится нормально во всех буферах
а вот так так:
:bufdo normal GoEnd file
уже завершится с ошибкой. Что бы все заработало надо сделать так:
:bufdo! normal GoEnd file

Собственно это все на сегодня. За мой первый пост на хабре ногами прошу не пинать. Исправления, дополнения, замечания — приветствуются.
Tags:
Hubs:
+34
Comments18

Articles

Change theme settings