我想从vim(:help :!
)运行系统命令,我想将字符串变量的内容作为该命令的stdin传递。
我已经知道我可以pass lines from the current buffer as stdin(见:help :w_c
)。但我不想修改当前的缓冲区,我也不想创建新的缓冲区。
我知道我可以将字符串写入临时文件,然后将该文件作为输入进行管道并删除它。现在,这是我知道的应用程序的最佳解决方案。但是,首先避免创建文件会更清晰。
可以吗?
答案 0 :(得分:6)
所以基本上,你有一个变量,比方说,一个字符串,你想把这个变量传递给一个外部命令,并在一个变量而不是缓冲区中获得返回值。
如果上述情况正确,您可以这样做,请参阅以下示例:
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
答案 1 :(得分:2)
对于后人来说,这是我在黑客攻击时想到的另一个答案。
@ Kent的答案看起来像是将stdin传递给命令的规范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。哦,好吧。
答案 2 :(得分:1)
您还可以将列表传递给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月,如果这对您很重要,则会删除尾随空行)