捕获与搜索匹配的行数

Rem*_*man 0 vim search lines pattern-matching match

例:

搜索:

/lastword\s*\n\zs\(\s*\n\)\{6}\ze\s*startword
Run Code Online (Sandbox Code Playgroud)

此搜索在以"lastword"结尾的行和以"startword"开头的行之间搜索6个空行

我想抓住与此搜索匹配的空行的亚麻布.

有没有办法在vim中这样做?

Pet*_*ker 5

您可以使用:g:number(或:#简称)打印带行号的行.

:g/lastword\s*\n\zs\(\s*\n\)\{6}\ze\s*startword/#
Run Code Online (Sandbox Code Playgroud)

要捕获此内容,您必须使用:redir将输出重定向到其他位置.在下面这种情况下,我们将其重定向到unamed寄存器(@")

:redir @"|execute 'g/pattern/#'|redir END
Run Code Online (Sandbox Code Playgroud)

注:必须使用:execute:g否则redir END将与每个匹配行执行:g命令.

现在它将通过:#起始线打印,这不是我们想要的(我们想要foo和之间的空行bar).我们可以使用:#命令范围来完成此任务.

:redir @"|execute 'g/foo\_.*bar/+,/bar/-#'|redir END
Run Code Online (Sandbox Code Playgroud)

现在+,/bar/-,范围转换为开始下一行(+),然后搜索bar(/bar/)然后减去一行(-).我们可以简化一些,因为我们知道空行的数量应该是6.

:redir @"|execute 'g/foo\_.*bar/+#6'|redir END
Run Code Online (Sandbox Code Playgroud)

我们可以通过将内容放入新缓冲区并删除多余的行来进一步实现.

:redir @"|exe 'g/pattern/+#6'|redir END|new|pu|%s/\d\+\zs.*//|%le|g/^$/d
Run Code Online (Sandbox Code Playgroud)

这里有很多内容,但我们的想法是捕获输出,打开一个新的缓冲区,粘贴内容,然后清理输出.

替代

或者awk可能会让这更容易一些.在当前Vim缓冲区上运行以下命令:

:%!awk '/lastword\s*$/,/^\s*startword/ { if($0 ~ /^\s*$/) { print NR} }'
Run Code Online (Sandbox Code Playgroud)

有关更多帮助请参阅:

:h :g
:h :redir
:h :exe
:h :range
:h :new
:h :pu
:h /\zs
:h :le
:h :d
Run Code Online (Sandbox Code Playgroud)