Как записать содержимое буфера в стандартный вывод? - PullRequest
30 голосов
/ 10 июля 2010

Есть ли шанс записать содержимое текущего буфера vim в стандартный вывод?

Я бы хотел использовать vim для редактирования содержимого, которое было передано через стандартный ввод, без необходимости временного файла для извлеченияизмененный контент (в Linux / Unix).

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

Ответы [ 8 ]

21 голосов
/ 17 августа 2012

Я думаю :w !tee будет работать идеально,

19 голосов
/ 11 июля 2010

Поскольку вы используете Linux / Unix, вам также может быть интересно попробовать moreutils .Он предоставляет команду с именем vipe, которая читает из stdin, позволяет редактировать текст в $EDITOR, а затем печатает измененный текст в stdout.

. Поэтому убедитесь, что вы установили свой редакторVim:

export EDITOR=vim

И тогда вы можете попробовать эти примеры:

cat /etc/fstab | vipe
cut -d' ' -f2 /etc/mtab | vipe | less
7 голосов
/ 10 июля 2010

Чтение со стандартного ввода:

echo "hey" | vim  -

Когда вы :w, вам все равно придется дать ему имя файла.

Программы, которые используют vim в качестве EDITOR, например crontab -e, передают ему имя файла, чтобы пользователь мог просто :x и не беспокоиться о именах файлов.

EDIT

Вы также можете сделать что-то вроде этого:

mkfifo /tmp/some_pipe
echo "hey" > /tmp/some_pipe ; cat /tmp/some_pipe

А из другого процесса (или терминала)

vim /tmp/some_pipe

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

5 голосов
/ 17 февраля 2015

Чтобы напечатать буфер на стандартный вывод оболочки, vim необходимо запустить в режиме Ex, в противном случае он откроет «обычный» путь с собственным окном и очистит все выходные буферы при выходе.

Вот самый простой рабочий пример:

$ echo foo | vim -es '+%print' '+:q!' /dev/stdin
foo

Необходимо указать специальный файловый дескриптор для стандартного ввода (/dev/stdin), чтобы предотвратить появление дополнительных раздражающих сообщений.

А вот несколько примеров разбора строк:

$ echo This is example. | vim -es '+s/example/test/g' '+%print' '+:q!' /dev/stdin
This is test.
$ echo This is example. | vim - -es '+s/example/test/g' '+%print' '+:q!'
Vim: Reading from stdin...
This is test.

Вот простой пример использования ex, который эквивалентен vi -e:

ex -s +%p -cq /etc/hosts

Связанный:

2 голосов
/ 30 июня 2016

Попробуйте что-то вроде:

{ FROMCMD | vim - 8>&1 >&9 | tac | tac | TOCMD; } 9>&1

и используйте ': w! Cat> & 8', когда закончите редактирование

'TAC | tac 'гарантирует, что TOCMD не получит никаких данных до тех пор, пока вы не создадите vim, это полезно только в том случае, если TOCMD пишет в терминал, чтобы не создавать беспорядка во время работы vim.

Обратите внимание, что выполнение 'less' в качестве вашего TOCMD (или любой другой программы, выполняющей некоторые операции с терминалами) не будет работать должным образом, поскольку даже если вы задерживаете данные, процессы по-прежнему запускаются «одновременно» и получить доступ к терминалу одновременно.

2 голосов
/ 20 января 2015

Использование :print записывает в stdout, особенно если vim запускается с опциями -E и -s, что приводит к неинтерактивному и бесшумному запуску.См. :h -E и :h -s-ex:

The output of these commands is displayed (to stdout):
                        :print                          
                        :list
                        :number
                        :set      to display option values."

Используйте :%print для печати всего текущего буфера.

1 голос
/ 09 июня 2014

vim может использоваться в каналах как полнофункциональный фильтр с явными именами для stdin и stdout, как в следующем примере:

echo xxx                                             |
vim                                                  \
  -esnN -i NONE                                      \
   +'1 s /x/y/g | 1 s /^/Hallo / | x! /dev/stdout'   \
   /dev/stdin                                        |
cat -n

Сокращение /dev/stdin с помощью - не будет работать, даже не с флагом -v.

1 голос
/ 26 октября 2012

Вы также можете использовать pipe.vim . Он использует временный файл, но, по крайней мере, вам не нужно беспокоиться об этом в своем собственном скрипте.

Во второй части вашего вопроса вы используете параметр командной строки -s с vim, чтобы переназначить :w в другое значение (например, :w !tee).

...