是否有机会将当前vim缓冲区的内容写入stdout?
我想使用vim编辑通过stdin传递的内容 - 无需临时文件来检索修改后的内容(在Linux / Unix上)。
插件/脚本 - 退出或保存时是否可能将缓冲区内容放入stdout?
答案 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)
这篇文章给了我一个想法:将缓冲区/或选择复制到剪贴板:
安装 xclip
(任何 Linux 发行版包管理器都应该安装它。)
执行这个 vim 命令:
:w !xclip
如果您只想复制某些行,请先使用(普通模式)V
选择 tem,然后发出上述命令。