Бывают ситуации когда нужно выполнить какую-то последовательность действий одновременно в нескольких файлах. Конечно, для этого можно использовать разные инструменты (навскидку: 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
Собственно это все на сегодня. За мой первый пост на хабре ногами прошу не пинать. Исправления, дополнения, замечания — приветствуются.
Рассмотрим простой пример: вставка строки в начало каждого файла.
По ходу выполнения этой простой задачи могут возникнуть некоторые нюансы использования 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
Собственно это все на сегодня. За мой первый пост на хабре ногами прошу не пинать. Исправления, дополнения, замечания — приветствуются.