如何轻松转义命令行过滤器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何轻松转义命令行过滤器相关的知识,希望对你有一定的参考价值。
我见过关于在类型的Vim中执行管道的讨论
:%! cmd1 | cmd2 | ...
它也适用于:w
:.w !cat | cat
它适用于:r
:r !echo hello | cat
:r !ls | grep .mp4
但是第二次我尝试了一些更有野心的东西,比如说,awk
,它停止工作:
:r !ls | awk '{printf ""%s"
", $0}'
E499: Empty file name for '%' or '#', only works with ":p:h"
我已经尝试了几十种语法变体来使它工作,包括在!
和()
之后围绕整个命令行,但它只是拒绝工作说一些关于空文件名。这就是让我在Google上搜索并找出管道是否真的在Vim中工作的原因。事实是,这不是awk的问题。以下是在bash shell上使用相同的命令行会发生的情况:
$ ls | awk '{printf ""%s"
", $0}'
"somefile1"
"somefile2"
"somefile3"
"somefile4"
它也适用于sh
(或我的系统上的dash
)。
如何让vim停止误解我的输入?实际上,我只是想出了解决这个问题的具体问题的解决方案。你必须逃避%
所以它不会将其解释为打开文件的名称。
:r !ls | awk '{printf ""\%s"
", $0}'
^
然而,这仍然是烦人的行为(和IMO混淆,Vim逃脱%
看起来就像awk的逃脱;人们怎么会知道这样做不会导致awk输出字面上"%s"
?这是我疯狂猜测的部分) 。
我想知道是否有办法完全逃脱filter
(!
之后的部分),这样我就不必慢慢解析我刚刚写的东西和特殊情况它只是为了Vim。过度复杂的转义很快就变得难以理解,而且在元编程方面是我的烦恼之一。
当然必须有一种简单的方法来告诉Vim忽略像%
等人的字符,然后将它们原样传递给shell,以便我可以在shell上测试我的命令并将它们复制/粘贴到Vim中,而不必担心手动逃避特定角色,因为我可以想象很容易成为屁股的巨大痛苦。
实际上,这是一个XY问题。不过,我必须在一个不同的问题上发布原始问题,因为Y
问题非常有趣,我想知道。我将在评论中发布X
问题的链接。
你使用shellescape()
的尝试很接近。你错过了什么:
- 对于
:!
(和:r !
),你需要将1
传递给{special}
旗帜。 - 您只能使用它来转义单个命令行参数,而不是整个命令行。由于您在最后一个(
awk
脚本)参数中只有关键字符,我们只需要它:
:exe 'r ! ls | awk ' . shellescape('{printf ""%s"
", $0}', 1)
以上是关于如何轻松转义命令行过滤器的主要内容,如果未能解决你的问题,请参考以下文章