在一个长文件中,我想搜索一个大约匹配200行左右的模式。匹配的行位于文件中的随机位置。
当一行匹配时,仅该行本身是相关的,上下无上下文。
通常,我将使用
/
搜索并使用n
。但这意味着一次在屏幕上只有一两个相关行。
暴力破解方法是删除所有不匹配的行,并在以后撤消该删除。但这在各种方面都是很丑陋的,即使它不会以持久的撤消而结束。
#1 楼
:vimgrep pattern %
:cwindow
vimgrep
将在当前文件(%
)或您指定的任何文件中搜索您的模式。cwindow
随后将在窗口中打开仅显示所需行的缓冲区。您可以在cwin
缓冲区中几乎使用任何导航/搜索命令。按回车跳到源文件中光标下方的行。要获得帮助:
:help vimgrep
:help cwindow
#2 楼
您可以使用:g/{pattern}
列出所有匹配的行
(可以省略
:print
命令;这是:g
的默认设置。)评论
这是“原始grep”(g / REgexp / p)。问题是您不能轻易跳到其中一场比赛,尽管...
–马丁·图尔诺伊(Martin Tournoij)
15年2月28日在19:44
@Carpetsmoker:你是对的;为此,我有一个插件,请参见其他答案。
– Ingo Karkat
15年2月28日在20:00
在许多情况下这可能很有用。可以将输出重定向到新的缓冲区吗?这样一来,仍然可以突出显示语法。 (嗯...这引起了另一个问题,请稍等...)
– Volker Siegel
15年2月28日在20:18
@IngoKarkat是g的意思。我认为这是一个全球模式。我通常使用斜杠/ pattern进行VI搜索,这样可以找到所有出现的情况。可以通过按字母n导航到他们
–亚历山大·卡斯卡(Alexander Cska)
19年6月13日在8:23
@AlexanderCska:不,它不是搜索的修饰符,而是一个单独的命令:g [lobal],它以模式作为参数。您可以在:help:global中找到所有详细信息。
– Ingo Karkat
19年6月13日在9:41
#3 楼
您可以使用foldmethod
和foldexpr
选项折叠不相关的行。搜索之后,最后的搜索存储在
@/
寄存器中。因此,您可以轻松收起所有不匹配的内容(仅适用于单行匹配):在Vim Tips Wiki上可以找到您可以显示或隐藏的上下文行的折叠或与多行匹配的内容。
评论
似乎需要设置foldlevel = 0?但这也许是默认的。
– Volker Siegel
2015年2月28日,下午3:16
是的,默认值为零,但是如果没有默认值,则添加默认值不会有问题。 :-)
–本
2015年2月28日,下午3:18
但是现在...如何再次将其切换回无痕迹?
– Volker Siegel
15年2月28日在3:23
在正常模式下,您可以使用“ zi”来切换折叠状态。
– John O'M。
15年2月28日在4:04
在大多数情况下,我首先使用:tab sp来获取文件的新视图。然后返回就很简单了::close或其他任何杀死制表符的方法。
–本
15年2月28日在17:49
#4 楼
[d]删除所有不匹配模式的行::g!/pattern/d
或更简单(感谢“ B Layer”的评论):
:v/pattern/d
评论
是的,但是使用等效的:v而不是:g!更常规。 (我不记得上次看到后者使用的时间,TBH!)
– B层
18年6月12日在4:06
#5 楼
如果顺序无关紧要,则只需移动行即可。:g/pat/m0
有关更多帮助,请参见:
:h :g
:h :m
评论
而且:g / pat / m $(将匹配的行移到末尾)也可以,
–张磊
16-09-28在9:05
#6 楼
如果要列出所有匹配的行(如我的其他答案),然后跳到一个特定的匹配项,我的FindOccurrence插件为此提供了[/
映射(最后一个搜索模式为[n
,而不是查询一个)。 [/pattern
列出类似:g/pattern
的列表,但随后询问要跳转到的匹配项编号。#7 楼
另一种方法是使用:h :ilist
,我用它来获得手册页的概述。结果看起来像这样:~/find.~
1: 3 NAME
2: 6 SYNOPSIS
3: 9 DESCRIPTION
4: 18 OPTIONS
5: 93 EXPRESSION
6: 779 EXAMPLES
7: 877 HISTORY
8: 931 BUGS
这是一个小函数,可让您选择按索引转到结果行:
可以像这样使用:
function! s:select_ilist(ilist_result)
if empty(a:ilist_result) || a:ilist_result =~# '^\_s*Error'
return
endif
let select = input(a:ilist_result . "\ngoto : ")
if empty(select) | return | endif
" ilist result starts with '\nfilename\n', filename can be empty
let lines = split(a:ilist_result[stridx(a:ilist_result, "\n", 1) : ], "\n")
if select <= 0 || select > len(lines) | return | endif
exec matchstr(lines[select-1], '^\v\s*\d+\:\s+\zs\d+')
endfunction
评论
:vimgrep可以缩写为:vim
– D. Ben Knoble♦
18年6月11日在14:51
我如何再次回到缓冲区?
–pasha
18/12/2在12:19
还应如何关闭缓冲区?提前致谢
–pasha
18/12/2在12:23
从quickfix(窗口)缓冲区中,您可以在任意行上按回车键,以跳到原始缓冲区中的该位置。您可以使用:ccl [ose]在任何地方关闭cwindow缓冲区,或者通常关闭缓冲区(例如,切换到它和:bd)。您可以通过再次运行:cw [indow]重新打开quickfix缓冲区,它将使用您的上一次vimgrep结果。
–扎克·英格布雷森(Zach Ingbretsen)
19年3月23日在12:59