捕获与搜索匹配的行数

时间:2016-11-17 17:37:05

标签: search vim pattern-matching match lines

示例:

搜索:

/lastword\s*\n\zs\(\s*\n\)\{6}\ze\s*startword

此搜索搜索以" lastword"结尾的行之间的6个空行。和一行以" startword"

开头

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

有没有办法在vim中执行此操作?

1 个答案:

答案 0 :(得分:5)

您可以使用:g:number(或简称为:#)打印出包含行号的行。

:g/lastword\s*\n\zs\(\s*\n\)\{6}\ze\s*startword/#

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

:redir @"|execute 'g/pattern/#'|redir END

注意:必须将:execute:g一起使用,否则redir END将在:g命令的每个匹配行上执行。

现在它将通过:#打印出不是我们想要的起始行(我们想要foobar之间的空行)。我们可以使用带有:#命令的范围来完成此任务。

:redir @"|execute 'g/foo\_.*bar/+,/bar/-#'|redir END

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

-

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

:redir @"|execute 'g/foo\_.*bar/+#6'|redir END

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

替代

另外,awk可能会让这更容易一些。在当前Vim缓冲区上运行以下命令:

:redir @"|exe 'g/pattern/+#6'|redir END|new|pu|%s/\d\+\zs.*//|%le|g/^$/d

如需更多帮助,请参阅:

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