如何轻松逃脱命令行过滤器 [英] How to easily escape a command-line filter

查看:85
本文介绍了如何轻松逃脱命令行过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过有关在Vim中执行管道的讨论

I've seen discussions about performing pipes in Vim of the type

:%! cmd1 | cmd2 | ...

它与:w 以及

:.w !cat | cat

它与:r

:r !echo hello | cat
:r !ls | grep .mp4

但是第二个我尝试了一些更宏大的东西,例如 awk ,它将停止工作:

But the second I try something more ambitious, like, say, awk, it stops working:

:r !ls | awk '{printf "\"%s\"\n", $0}'
E499: Empty file name for '%' or '#', only works with ":p:h"

我已经尝试了多种语法上的变体来使其正常工作,包括在整个命令行之后(),但是它只是拒绝说出空文件名。这就是促使我在Google上进行搜索并确定管道在Vim中是否真正起作用的原因。问题是,awk没问题。在bash shell上使用相同的命令行会发生以下情况:

I have tried dozens of variations on the syntax to get it to work, including surrounding the entire command-line after ! with (), but it just refuses to work saying something about an Empty file name. That's what led me to search on Google and find out whether or not piping actually works in Vim. Thing is, it's not a problem with awk. Here's what happens with that same exact command-line on a bash shell:

$ ls | awk '{printf "\"%s\"\n", $0}'
"somefile1"
"somefile2"
"somefile3"
"somefile4"

它也可以在 sh (或 dash )。

如何使vim停止误解我的输入?实际上,我只是想出了解决该特定问题的解决方案。您必须转义,因此它不会将其解释为已打开文件的名称。

How do I make vim stop misinterpreting my input? Actually, I just figured out the solution to the specific problem that spurred this question on. You have to escape the % so it doesn't interpret it as the name of the opened file.

:r !ls | awk '{printf "\"\%s\"\n", $0}'
                         ^

但是,这仍然是令人讨厌的行为(并且使IMO困惑,Vim为进行的转义看起来就像是awk的转义;应该怎么知道这样做那不会导致awk从字面上输出%s \n ?这是我的一个疯狂猜测)。

However, this is still annoying behavior (and confusing IMO, Vim's escape for % looks just like awk's escapes; how is one supposed to know that doing that won't cause awk to output literally "%s"\n? It was a wild guess on my part).

我想知道是否有一种方法可以完全摆脱过滤器(在<$ c之后的部分$ c>!),这样我就不必慢慢解析我刚刚写的内容,而仅对Vim进行特殊处理。过度复杂的转义很快变得难以理解,这是元编程时我讨厌的东西之一。

I would like to know if there's a way to totally escape a filter (the part after the !) so that I don't have to slowly parse what I just wrote and special-case it just for Vim. Over-complicated escaping quickly gets unreadable and is one of my pet peeves when it comes to meta-programming.

当然告诉Vim忽略诸如等字符的方式,并将它们原样传递给Shell,以便我可以在Shell上测试命令并复制/粘贴它们进入Vim,而不必担心手动转义特定字符,因为我可以想象,这很容易在屁股上变成巨大的痛苦。

Surely there must be a simple way to tell Vim to ignore characters like % et al, and pass them to the shell as-is, so that I can test my commands on the shell and copy/paste them into Vim without having to worry about manually escaping specific characters, because I can imagine that easily becoming a huge pain in the ass.

实际上,这有点XY问题。不过,我必须将原始问题发布到另一个问题中,因为 Y 这个问题真的很有趣,我想知道。我将在评论中发布 X 问题的链接。

And actually, this has been a bit of an XY problem. I'll have to post the original problem in a different question, though, because the Y question is really interesting and I would like to know. I'll post a link to the X question in the comments.

推荐答案

您使用 shellescape()的尝试已结束。您缺少的内容:

Your attempts at using shellescape() are close. What you're missing:


  • 对于:!(和:r!),则需要传递 1 作为 {特殊}

  • 您只能使用它转义单个命令行参数,而不能转义整个命令行。由于您在最后一个( awk 脚本)参数中仅包含关键字符,因此我们仅在其中使用它:

  • For :! (and :r !), you need to pass 1 for the {special} flag to it.
  • You can only escape a single command-line argument with it, not the entire command-line. As you only have critical characters in the last (awk script) argument, we only need it there:
:exe 'r ! ls | awk ' . shellescape('{printf "\"%s\"\n", $0}', 1)

这篇关于如何轻松逃脱命令行过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆