我想创建一个'quickfix'列表(请参阅:help quickfix
),其中包含所有包含“abc”但不包含“xyz”的行的文件。我希望我可以运行以下vim ex命令:
:grep -nHr abc * | grep -v xyz
不幸的是,vim不喜欢“管道”,命令失败。在vim中执行此操作的最佳方法是什么?
答案 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