Как записать весь буфер в стандартный вывод из командной строки?

10

Я хотел бы записать весь буфер в стандартный вывод ( /dev/stdout) вместо файла, и следующая команда работает, как и ожидалось, при редактировании файла:

:w >> /dev/stdout

Подсказка: нажмите Control+, Lчтобы обновить экран.

Но это не работает, как ожидалось, когда я пытаюсь сделать то же самое из командной строки ( не в интерактивном режиме ), например:

$ echo This is example. | vim - '+:w >> /dev/stdout' '+:q!'
Vim: Reading from stdin...

Же с :w !tee, :x! /dev/stdout, :%printи аналогичные.

Перед тем как уйти, он говорит: [Device] 1L, 17C appended.

Есть ли способ заставить vim записать стандартный ввод в стандартный вывод в середине канала? Может это как-то буферизуется?

kenorb
источник
4
Просто любопытно, что ты пытаешься достичь? Например, что vim сделает для вас здесь, а какой-то другой инструмент не сможет?
Джей Томпсон
1
@JayThompson Я пытаюсь использовать vimдля анализа файлов вместо sed(например, массовые повторные сложные изменения в нескольких больших файлах). В примере ничего не делается для того, чтобы он был простым и не создавал потенциальную копию другого поста .
Кенорб
Вы знаете о vipe, так по какой причине вы его не используете?
Муру
@muru Я еще не использовал его, не так много документации, и это не по теме здесь.
Кенорб
Вопросы о vipe могут быть, но нет никаких причин, по которым это не может быть ответом. Поэтому мне интересно, почему я не должен публиковать это как ответ.
Муру

Ответы:

9

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

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

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

или даже короче

$ echo foo | ex +%p -cq! /dev/stdin
$ echo foo | ex +"%p|q!" /dev/stdin

Примечание. Команда vim -eв основном эквивалентна exкоманде.

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


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

$ echo This is example. | vim -e '+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.

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


Связанные с:

kenorb
источник
1
Вы можете просто сделать, +q!а не +:q!, верно?
Андрей
@AndrewMacFie Это тоже самое, обновлено, спасибо.
Кенорб
3

vipeэто удобный инструмент для редактирования конвейеров, входящий в состав moreutilsпакета. Это обертка для редакторов (в том числе и viназвание). Он использует EDITORпеременные среды для установки редактора, так, как и с другими инструментами , которые используют EDITOR(такие как crontab, visudoи т.д.), вы можете действие сценария , используя этот переменную. Например, вы можете изменить это, чтобы сделать:

$ echo foo | EDITOR='vim +:s/foo/bar/ +wq' vipe | tail
bar

Конечно, сложные действия могут перейти в кавычки, поэтому вы можете написать скрипт:

#! /bin/sh

vim "+:s/foo/bar" '+wq' "$@"

И использовать EDITOR="sh /path/to/script".

Мур
источник