从 Vim 内部执行 Greping(使用管道)
我想创建一个“quickfix”列表(请参阅 :help fastfix
),其中包含包含“abc”但不包含“xyz”行的所有文件。我希望我可以运行以下 vim ex 命令:
:grep -nHr abc * | grep -v xyz
不幸的是,vim 不喜欢“管道”并且命令失败。在 vim 中执行此操作的最佳方法是什么?
I want to create a 'quickfix' list (see :help quickfix
) with all files that contain lines with "abc" but not "xyz". I was hoping I could run the following vim ex command:
:grep -nHr abc * | grep -v xyz
Unfortunately, vim doesn't like the "pipe" and the command fails. What is the best way to do this from within vim?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
很多年过去了,但我找到了更直接的替代方案。 vim 中的
cexpr
命令。它几乎实现了 @jwd 和 @skeept 的答案,并且更加灵活,因为它接受列表。下面是我自己使用管道的示例。我在工作笔记中的所有问题前都加上
Q:
前缀,以便快速找到它们。我想使用quickfix list和vim来浏览问题,首先查看最近的问题。相关摘自vim帮助。
It's many years later, but I found more direct alternative.
cexpr
command in vim. It pretty much implements the answers from @jwd and @skeept, and is a bit more flexible because it accepts a list.Below is an example use of my own which uses pipes. I prefix all my questions in my work notes with
Q:
to find them quickly. I wanted to use quickfix list and vim to browse through questions, viewing the most recent first.Relevant excerpt from the vim help.
出于某种原因,我不能放过这个!
怎么样使用
:!grep ... > filename
后跟:cf filename
,这将以快速修复列表的形式打开输出。For some reason I can't leave this one alone!
How about use
:!grep ... > filename
followed by:cf filename
, which will open the output as a quickfix list.我刚刚弄清楚如何转义
:grepprg
以使用管道。该管道需要双重转义。看来 Vim 最终将 grepprg 的值作为命令材料进行处理。如果只转义一次管道,它就会被解释为 Vim 语法。
所以我现在在
.vimrc
中的内容是这样的:管道被转义为
\\\|
:一个转义的反斜杠和一个转义的管道以生成\|
,再经过一轮处理,最终得到|
。基于此示例,可以自定义
grep
命令以包含任意 Unix 管道。如果您只想修剪快速列表的结果,或在结果中进行搜索,可以使用交互式方式。
执行
:grep
后,在拆分窗口中打开一个缓冲区,其中包含快速列表本身:要充分利用此功能,请了解拆分窗口,特别是使用 Ctrl-W 在拆分窗口之间导航Ctrl-W 和其他 Ctrl-W 命令。
在快速修复结果窗口中,您可以通过以普通方式搜索来“优化搜索”,就像在任何缓冲区中一样。无论您导航到哪一行,您只需按该行上的
Enter
即可跳转到其他窗口中的该快速列表项。光标自动转到该窗口:要返回快速列表结果以搜索其他内容,请使用 Ctrl-W Ctrl-W。您还可以通过从
:cope
缓冲区中删除不需要的行来修剪快速列表结果。默认情况下,缓冲区是不可修改的,因此首先您必须确保光标位于该窗口中,然后:然后您可以执行诸如
删除所有包含 xyz 的结果之类的操作。现在只有剩下的行才是快速修复列表的一部分。
I just figured out how to escape
:grepprg
to use a pipe.The pipe requires double escaping. It seems that Vim ends up processing the value of
grepprg
as command material. If you escape the pipe just once, it is interpreted as Vim syntax.So what I have now in my
.vimrc
is this:The pipe is escaped as
\\\|
: an escaped backslash and an escaped pipe to produce\|
, which undergoes one more round of processing to end up with|
.Based on this example, it is possible to customize your
grep
command to include arbitrary Unix plumbing.If you just want to trim the results of a quicklist, or to search within the results, there is an interactive way.
After doing the
:grep
, open a buffer in a split window which contains the quicklist itself:To make the best use of this, learn about split windows and in particular, navigation between split windows using Ctrl-W Ctrl-W, and other Ctrl-W commands.
In the quickfix result window, you can "refine your search" by searching in the ordinary way, like in any buffer. Whatever line you navigate to, you can just hit
Enter
on that line to jump to that quicklist item in your other window. The cursor automatically goes to that window: to return to the quicklist results to search for something else, use Ctrl-W Ctrl-W.You can also trim the quicklist results simply by deleting unwanted lines from the
:cope
buffer. The buffer is unmodifiable by default, so first you have to make sure your cursor is in that window and then:Then you can do something like
to delete all results that contain
xyz
. Only the lines which remain are now part of the quickfix list.你可以分两步完成:
如果你经常改变模式,你可能可以使用一个函数来包装它
以下并不完美,但有效:
然后使用以下方式调用它:
它似乎对我有用,但我也收到错误消息“trailin charathers”
(您可能需要键入以清除屏幕)。
you can do it in two steps:
if you change frequently of patterns yo probably can use a function to wrap this
the following is not perfect, but works:
and then call it using:
it seems to work for me but I also get an error message "trailin charathers"
(you may need to type to clear the screen).
您可以设置
grepprg
,它定义 Vim 使用什么命令来执行:grep
。它可以包含管道,但很难使用:set
正确转义。如果您使用:let
代替,则可以传递表达式。使用该表达式的字符串文字可提供更简单的转义规则,因此您可以使用更具可读性的值。下面是一个示例,首先过滤掉不需要的文件,然后提供与 PCRE 的多行匹配:所有反斜杠都按原样传递到 shell,但紧接在
%
之前的反斜杠除外,因为它们在以下情况下被消耗:防止扩展到文件名和路径。当然,这会影响您的所有
:grep
,但您可以使用:set gp&
恢复为默认命令。You can set
grepprg
, which defines what command Vim uses to execute:grep
. It can contain pipes, though it's difficult to get the escaping correct using:set
. If you use:let
instead, you can pass an expression. Using a string literal for that expression provides simpler escaping rules, so you can use a more readable value. Here's an example that filters out unwanted files first, then offers multiline matching with PCRE:All the backslashes are passed to the shell as-is with the exception of those that immediately precede
%
, as they are consumed when preventing expansion into filenames and paths.Of course, that would affect all your
:grep
s but you can revert to the default command with:set gp&
.