如何轻松转义命令行过滤器

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)

以上是关于如何轻松转义命令行过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何在命令行启动参数上转义文件路径中的空格

如何在命令行启动参数上转义文件路径中的空格

如何在 Windows 中轻松查看和过滤 Android 的 logcat?

如何转义任意字符串以用作 Bash 中的命令行参数?

关闭Django模板的自动转义

如何阻止我的命令行参数在 Maven 插件中被转义?