来自Vim内的Gre((带管道)

时间:2011-05-18 23:42:50

标签: vim grep

我想创建一个'quickfix'列表(请参阅:help quickfix),其中包含所有包含“abc”但不包含“xyz”的行的文件。我希望我可以运行以下vim ex命令:

:grep -nHr abc * | grep -v xyz

不幸的是,vim不喜欢“管道”,命令失败。在vim中执行此操作的最佳方法是什么?

5 个答案:

答案 0 :(得分:3)

出于某种原因,我不能单独留下这个!

如何使用:!grep ... > filename后跟:cf filename,这将打开输出作为quickfix列表。

答案 1 :(得分:1)

你可以分两步完成:

:!(grep -nHr abc * | grep -v xyz >| qf.txt)
:cfile qf.txt | copen

如果你频繁更改模式,你可能会使用一个函数来包装它 以下不完美,但有效:

fu! Mygrep(pat1, pat2)
  let cmd = "silent !(grep -nHr " . a:pat1 . " * | grep -v " . a:pat2 . " >| qf.txt)"
  silent exec cmd
  cfile qf.txt
  copen 
endfunction

然后使用:

调用它
:call Mygrep("abc", "xyz")

它似乎对我有用,但我也收到错误消息“trailin charathers” (您可能需要键入以清除屏幕)。

答案 2 :(得分:1)

已经很多年了,但是我发现了更多直接的选择。 vim中的cexpr命令。它几乎实现了@jwd和@skeept的答案,并且由于接受了列表而更加灵活。

下面是我自己使用管道的示例。我在工作笔记中的所有问题都以Q:开头,以快速找到它们。我想使用快速修复列表和vim浏览问题,查看最新的问题。

:cexpr system("grep -R --line-number Q: --exclude '*~' ~/_Notes/work-log/ \| sort \| tac")

vim帮助中的相关摘录。

:cex[pr][!] {expr}  Create a quickfix list using the result of {expr} and
            jump to the first error.
            If {expr} is a String, then each new-line terminated
            line in the String is processed using the global value
            of 'errorformat' and the result is added to the
            quickfix list.
            If {expr} is a List, then each String item in the list
            is processed and added to the quickfix list.  Non
            String items in the List are ignored.
            See |:cc| for [!].
            Examples: >
                :cexpr system('grep -n xyz *')

答案 3 :(得分:0)

我刚刚想出如何逃避:grepprg使用管道。

  

就我而言,我的:grepprg基于GNU Idutils的lid实用程序。我希望对lid程序的输出进行排序。这是因为当我使用模式时,lid无序地找到匹配项。我想查找一个类似于pthread.*lock的模式并逐步执行匹配以跟踪锁嵌,而不是以遵循ID数据库的内部顺序的方式在文件之间跳转由mkid生成,它交错来自不同文件的匹配。

管道需要双重逃逸。似乎Vim最终将grepprg的值作为命令材料处理。如果只转义一次管道,它将被解释为Vim语法。

所以我现在在.vimrc中的内容是:

:set grepprg=lid\ --substring\ --result=grep\ '\\<$*\\>'\ \\\|\ sort

管道以\\\|转义:转义为反斜杠和转义管道以生成\|,经过一轮处理以|结束。

基于此示例,可以自定义grep命令以包含任意Unix管道。


如果您只想修剪快速列表的结果,或者在结果中进行搜索,则可以采用交互方式。

在执行:grep之后,在包含快速列表本身的拆分窗口中打开一个缓冲区:

:cope[Enter]

要充分利用此功能,请了解分割窗口,尤其是使用Ctrl-W Ctrl-W和其他Ctrl-W命令在分割窗口之间导航。

在quickfix结果窗口中,您可以通过常规方式搜索来“优化搜索”,就像在任何缓冲区中一样。无论您导航到哪一行,您只需点击该行上的Enter即可跳转到其他窗口中的该快捷列表项目。光标自动进入该窗口:要返回快速列表结果以搜索其他内容,请使用Ctrl-W Ctrl-W。

您还可以通过删除:cope缓冲区中不需要的行来修剪快速列表结果。默认情况下缓冲区是不可修改的,因此首先必须确保光标位于该窗口中,然后:

 :set modifiable

然后你可以做类似

的事情
 :g/xyz/d

删除包含xyz的所有结果。现在只剩下的行现在是quickfix列表的一部分。

答案 4 :(得分:-1)

您可以设置grepprg,它定义了Vim用于执行:grep的命令。这可能需要一个管道,但我没有尝试过。

当然,这会影响所有你的:grep s