我已经看过有关在Vim中执行
类型管道的讨论:%! cmd1 | cmd2 | ...
它也适用于:w
:.w !cat | cat
它适用于:r
:r !echo hello | cat
:r !ls | grep .mp4
但是第二次我尝试了一些更雄心勃勃的事情,比如,awk
,它停止了工作:
:r !ls | awk '{printf "\"%s\"\n", $0}'
E499: Empty file name for '%' or '#', only works with ":p:h"
我已尝试了几十种语法变体来使其工作,包括在!
之后使用()
包围整个命令行,但它只是拒绝处理有关空文件的内容名称。这是导致我在Google上搜索并找出管道是否真的在Vim中工作的原因。事实是,它不是awk的问题。以下是在bash shell上使用相同的命令行会发生什么:
$ ls | awk '{printf "\"%s\"\n", $0}'
"somefile1"
"somefile2"
"somefile3"
"somefile4"
它也适用于sh
(或我系统上的dash
)。
如何让vim停止误解我的输入?实际上,我只是想出了解决这个问题的具体问题的解决方案。您必须转义%
,因此它不会将其解释为已打开文件的名称。
:r !ls | awk '{printf "\"\%s\"\n", $0}'
^
然而,这仍然是令人讨厌的行为(让IMO感到困惑,Vim在%
的逃脱看起来就像是awk的逃脱;人们怎么会知道这样做会赢得' t导致awk按字面输出"%s"\n
?这对我来说是一个疯狂的猜测。
我想知道是否有一种完全逃避filter
(!
之后的部分)的方式,这样我就不必慢慢解析我的意思为Vim编写和特殊情况。过度复杂的转义很快就变得难以理解,而且在元编程方面是我的烦恼之一。
当然必须有一种简单的方法来告诉Vim忽略像%
等字符,并按原样将它们传递给shell,以便我可以测试我的命令shell并将它们复制/粘贴到Vim中,而不必担心手动转义特定字符,因为我可以想象这很容易成为屁股的巨大痛苦。
实际上,这有点像XY问题。不过,我必须在不同的问题上发布原始问题,因为Y
问题非常有趣,我想知道。我会在评论中发布X
问题的链接。
答案 0 :(得分:1)
您使用shellescape()
的尝试即将结束。您所缺少的:
:!
(和:r !
),您需要将1
标志的{special}
传递给它。awk
脚本)参数中仅包含关键字符,因此我们仅在此处需要它::exe 'r ! ls | awk ' . shellescape('{printf "\"%s\"\n", $0}', 1)