如何将缓冲区内容写入stdout?

时间:2010-07-10 14:07:21

标签: shell vim stdout vi

是否有机会将当前vim缓冲区的内容写入stdout?

我想使用vim编辑通过stdin传递的内容 - 无需临时文件来检索修改后的内容(在Linux / Unix上)。

插件/脚本 - 退出或保存时是否可能将缓冲区内容放入stdout?

10 个答案:

答案 0 :(得分:21)

我认为:w !tee可以完美运作,

答案 1 :(得分:19)

由于您使用Linux / Unix,您可能也有兴趣尝试moreutils。它提供了一个名为vipe的命令,从stdin读取,允许您编辑$EDITOR中的文本,然后将修改后的文本打印到stdout

因此,请确保将编辑器设置为Vim:

export EDITOR=vim

然后你可以试试这些例子:

cat /etc/fstab | vipe
cut -d' ' -f2 /etc/mtab | vipe | less

答案 2 :(得分:7)

从stdin读取:

echo "hey" | vim  -

当你:w时,你还需要给它一个文件名。

使用vim作为EDITOR crontab -e的程序,如:x传递文件名,以便用户可以mkfifo /tmp/some_pipe echo "hey" > /tmp/some_pipe ; cat /tmp/some_pipe 而不用担心文件名。

修改

您也可以这样做:

vim /tmp/some_pipe

来自另一个流程(或终端)

{{1}}

请注意,写入管道会阻塞直到从中读取内容,并且读取将阻止直到写入内容,因此使用常规文件可能更安全。

答案 3 :(得分:5)

要将缓冲区打印到shell标准输出,vim需要在Ex模式下启动,否则它将打开" normal"使用自己的窗口并在退出时清除任何输出缓冲区。

这是最简单的工作示例:

$ 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

相关:

答案 4 :(得分:2)

使用: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打印整个当前缓冲区。

答案 5 :(得分:2)

尝试类似:

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

并在完成编辑后使用':w!cat>& 8'

'tac | tac'确保TOCMD在您完全访问之前不接收任何数据,这仅在TOCMD写入终端时才有用,这样当vim仍在运行时它不会弄得一团糟。

请注意,运行'less'作为您的TOCMD(或执行某些终端操作的任何其他程序)不会按预期工作,因为即使您延迟数据,这些进程仍然“同时”启动并且可能同时访问终端。

答案 6 :(得分:1)

您也可以使用pipe.vim。它确实使用了一个临时文件,但至少你不必在自己的脚本中担心它。

在问题的第二部分,您使用vim的-s命令行选项将:w重新映射到其他内容(例如:w !tee)。

答案 7 :(得分:1)

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}}旗帜。

答案 8 :(得分:0)

您可以使用ex-mode(p)rint命令打印要输出的任何行集。

打印所有行:

:1,$p

也打印所有行(%是范围1,$的简写)

:%p

打印4-10行:

:4,10p

打印包含FOO的下一行

/FOO/ p

打印所有包含FOO的行

g/FOO/ p

答案 9 :(得分:0)

这篇文章给了我一个想法:将缓冲区/或选择复制到剪贴板:

  1. 安装 xclip(任何 Linux 发行版包管理器都应该安装它。)

  2. 执行这个 vim 命令:

:w !xclip

如果您只想复制某些行,请先使用(普通模式)V 选择 tem,然后发出上述命令。