在《 Vim正则表达式》一文中,Oleg Raisky给出了以下命令,以将多行空行减少为一个空行:

我知道:g命令和正则表达式。但是我不明白/,/./-j的作用是什么。

#1 楼

确实是很巧妙。让我们分解一下。 ex命令

g/^$/xyzzy


将搜索所有空行,并对每个空行执行xyzzy命令(任意ex命令)。请注意,xyzzy不是真正的ex命令,根据下一段,它仅作为占位符存在。

这里的棘手之处在于,您所用的xyzzy“ command”还是另一个搜索命令。 :

,/./-j


,/./-指定范围。格式为<start>,<end>,并且因为逗号前没有任何内容,所以它假设当前行(找到空行的那一行)是开始。

逗号后面是/./-,表示搜索对于下一个字符(.表示任何字符),然后备份一行(/./-/./-1的缩写,因为如果未给出值则隐含一个)。您会在所操作的行之后的第一行非空白行中找到模式.。换句话说,范围的结尾是该行之后或该行之后的最后一个空白行您当前正在操作。

然后在该范围内执行联接。

如果范围的开始和结束相等(仅在其中一个空白行部分),join不会执行任何操作。如果它们不相等,则join会将它们全部连接起来。

这就是将多个空行合并为一个的方式。

让我们看一个示例(行号仅用于说明,它们不在实际文件中):

1 Line 1
2
3 Line 3
4 Line 4
5
6
7
8
9 Line 9


g/^$/命令将找到所有空行并对其执行操作(这些是第2、5、6、7和8行)。

对于第2行,,/./-j将设置2到2的范围(在第3行中找到下一个.,然后减去1得到2 )。在2,2范围内的联接不起作用。

对于第5行,,/./-j将设置5到8的范围(在第9行找到下一个.,然后减去1)。在范围5,8上的联接会将所有这些行连接在一起。

该操作不会在作为先前操作的一部分而消失的行上执行。那是因为处理在周期中早些时候删除的行是没有意义的。换句话说,因为第6至8行被删除(与第5行结合),所以全局命令不会这样做。

这是基于以下事实:vim文档陈述了一种两遍算法,一种用于标记行,一种用于执行操作。

评论


请注意,如果文件末尾有任何空行,则此命令将发出警告。

–通配符
16 Mar 15 '22 at 22:45