Найти в Дзене
Блокнот математика

Рубрика "Секреты Вим". Внешние фильтры

Фильтром называется утилита, которая принимает текст из STDIN и выдает текст в STDOUT. Может отфильтровывать, например, строки, как grep. Может что-то делать с ними, как fmt или однострочники на Perl. Может делать вообще что угодно, скажем, переводить или редактировать грамматику или, скажем, заменять недопустмые слова на эвфемизмы. В этой заметке обсудим средства Вим для пропускания текста через внешние фильтры.

Оглавление рубрики

Прежде всего, вспомним, как вызывать команды bash (или какая у вас оболочка) из Вим: посредством команды "восклицательный знак". Например, так:

:!ls -lstr *.txt

Восклицательный знак используется и в других случаях общения с системой.

Так,

:r! команда_bash

позволяет не просто выполнить команду, но вставить ее выдачу в текст. Команда :r (:read) вообще позволяет вставить файл, но в частности и выдачу команды bash.

Это удобно, например, для вставки списка файлов, или для искомого системным grep-ом, хотя в Вим есть для поиска по файлам удобные средства. Можно запустить что угодно, от однострочника на Перле до каких угодно программ, и вставить в текст то, что они выдадут на STDOUT.

Но это пока выполнение внешней команды без передачи ей текста. Но вот команда

:диапазон! фильтр

передает указанный диапазон строк внешнему фильтру и вставляет его выдачу в файл. Примеры:

.,+3!fmt
.,$!perl -E 's/42/666/g'

Можно немного упростить себе жизнь. Например, выделить текст и далее

!фильтр.

А ! с движением выпишет диапазон за вас. Скажем,

!3jfmt

Наконец, !!фильтр пропустит через фильтр указанное число строк:

12!!fmt

Указанная утилита fmt форматирует текст, вставляя символы конца строки, но с умом. При этом длинные строки укорачиваются, удобно бывает, см. man. Впрочем, для форматирования строк есть команда Вим gq. О ней в другой раз.

Я наиболее часто пользуюсь однострочниками. Например, удобно перевести столбец таблицы данных в другие единицы:

.,$! perl -pa -E '$F[1]*=3600; say"@F"'

пропускает строки с текущей (.) до конца ($) через скрипт, который обрабатывает входной поток STDIN построчно (-n), разделяет строку на слова (-a) и кладет их в массив @F. Берем второй элемент (второй столбец) $F[1] и делаем с ним что хотим. Потом выводим на STDOUT.

Удачи, коллеги!

Навигатор по каналу