如何从命令行将整个缓冲区写入标准输出?


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在管道中间将标准输入写入标准输出?也许以某种方式缓冲了吗?


4
只是好奇,您要完成什么?在这种情况下,vim会为您做什么,而其他一些工具可能不会呢?
杰·汤普森

1
@JayThompson我正在尝试vim用于文件解析而不是sed(例如,对多个大文件重复进行大量复杂的更改)。这个例子没有做任何事情,以保持它的简单,并没有做出其他的潜在的重复岗位
kenorb 2015年

您了解vipe,因此您不使用它的任何理由?
muru

@muru我还没有使用过,可用的文档不多,并且不在这里。
kenorb 2015年

有关vipe的问题可能是,但没有理由不能成为答案。所以我想知道为什么不应该将其发布为答案。
muru

Answers:


9

要将缓冲区打印到Shell标准输出,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)信号,因此它将永远不会到达其输入读取的末尾。


有关:


1
你可以做+q!而不是+:q!,对吧?
安德鲁

@AndrewMacFie这是同一件事,已更新,谢谢。
kenorb

3

vipe是用于编辑管道(moreutils程序包的一部分)的便捷工具。它是编辑器的包装器(包括vi为其命名的包装器)。它使用EDITOR环境变量设置编辑器,因此,像与使用其他工具EDITOR(如crontabvisudo等),您可以使用该变量脚本操作。例如,您可以将其更改为:

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

当然,复杂的动作可能会演变为引号,因此您可以编写脚本:

#! /bin/sh

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

并使用EDITOR="sh /path/to/script"

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.