我想从 vim ( :help :!
) 运行系统命令,并且我想将字符串变量的内容作为该命令的标准输入传递。
我已经知道我可以将当前缓冲区中的行作为标准输入(请参阅参考资料:help :w_c
)。但是我不想修改当前的缓冲区,也不想做一个新的缓冲区。
我知道我可以将字符串写入临时文件,然后将该文件作为输入进行管道传输并删除它。现在,这是我所知道的应用程序的最佳解决方案。但是首先避免创建文件会更干净。
可以做到吗?
我想从 vim ( :help :!
) 运行系统命令,并且我想将字符串变量的内容作为该命令的标准输入传递。
我已经知道我可以将当前缓冲区中的行作为标准输入(请参阅参考资料:help :w_c
)。但是我不想修改当前的缓冲区,也不想做一个新的缓冲区。
我知道我可以将字符串写入临时文件,然后将该文件作为输入进行管道传输并删除它。现在,这是我所知道的应用程序的最佳解决方案。但是首先避免创建文件会更干净。
可以做到吗?
所以基本上,你有一个变量,比如一个字符串,你想把这个变量传递给一个外部命令,并在一个变量而不是缓冲区中获取返回值。
如果上面是正确的,你可以这样做,看下面的例子:
let s="vim is good"
let r=system("sed 's/good/the best/'",s)
echo r
"display vim is the best
echo s
"display vim is good
对于后代,这是我在四处乱窜时想出的另一个答案。
@Kent 的答案看起来像是将标准输入传递给命令的规范 vim 方式。它使您免于管理临时文件。但是,如果(无论出于何种原因)您想完全避免创建文件的开销怎么办?这是一种方法。
基本形式是
echo your_string | your_command
当然,正确处理细节很容易出错,所以我建议将其包装在一个函数中:
function! RunCommandWithStdin(cmd, stdin_lines)
let l:stdin = shellescape(join(a:stdin_lines, "\\n"), 1)
execute '!echo -e' l:stdin '|' a:cmd
endfunction
快速健全性检查,使用patch
:
:!echo foo > bar
:!cat bar
foo
:call RunCommandWithStdin('patch bar', ['@@ -1 +1 @@', '-foo', '+~!@#$%^&*()'])
:!cat bar
~!@#$%^&*()
请注意,这似乎可以正确处理特殊字符。
缺点是它使用echo
,所以它可能仅限于 *nix-alikes。那好吧。
您还可以将列表传递给 system() 以为您的命令提供多于一行的 STDIN:
所以:
let s=["perl is good", "perl is complicated"]
let r=system("sed 's/perl/vim/'", s)
echo r
"vim is good
"vim is complicated
另请注意,在这种情况下,您可以使用 systemlist() 将结果作为列表获取(截至 2018 年 1 月,如果这对您很重要,尾随空行将被截断)