vim:如何插入 shell 命令的输出?

elb*_*rna 5 vim

假设我想编辑一个新的 libvirt XML 文件:

virsh dumpxml machine1 > machine2.xml
Run Code Online (Sandbox Code Playgroud)

然后我用打开文件vim

vim machine2.xml
Run Code Online (Sandbox Code Playgroud)

然后我想更改UUID。现在这样做,我用

:r ! uuidgen
Run Code Online (Sandbox Code Playgroud)

但新的 UUID 会插入到当前行下:

<uuid>6r123ttz-6t01-356t-1y7h-g7oe196c8u3m</uuid>
e67baf90-751b-4aea-a14b-aca1b881542b
Run Code Online (Sandbox Code Playgroud)

uuidgen我怎样才能将命令的输出插入当前行,这样如果我有

<uuid></uuid>
Run Code Online (Sandbox Code Playgroud)

(光标在 之间><),然后,通过执行uuidgen我得到

<uuid>e67baf90-751b-4aea-a14b-aca1b881542b</uuid>
Run Code Online (Sandbox Code Playgroud)

问题是:是否可以使用:rvim命令而不添加新行?

Ing*_*kat 7

:read是一个Ex 命令不幸的是,这些总是在完整的线路上工作。您要么必须先拆分,然后再加入前面和后面的行,要么使用不同的命令来解决这个问题。

:help i_CTRL-R命令可以插入任意寄存器内容。有一个特殊的表达式寄存器( :help quote=) 可以执行任何 Vimscript 表达式并使用其结果。最后,该system()函数执行外部命令并返回其输出。

因此(在插入模式下)<C-R>=system('uuidgen')<CR>将在当前位置插入命令的输出。不幸的是,输出有一个尾随换行符,并且该换行符被保留,因此</uuid>移动到下一行。system('uuidgen')[0:-2]为了避免这种情况,您可以通过或substitute(system('uuidgen'), '\n$', '', '')作为表达式截断输出。

对于重复插入,可以使用表达式历史记录来调用最后一个表达式(按<Up>);为了更加舒适,您可以为整个事物定义一个映射。


小智 4

我玩了一下,这并不完全符合你的要求,因为 :r 总是会输入换行符。但它应该做你想要的结果。

:.!UUID=`uuidgen` ; echo "<uuid>$UUID</uuid>"
Run Code Online (Sandbox Code Playgroud)

它将标准输出放在当前行(而不是光标处) - 智能是通过正在调用的命令完成的。