我认为以下命令应该工作:
:%s/^\(.*\)\(\n\1\)\+$/\1/
说明:
我们在整个文件上使用替换命令更改pattern为string:
:%s/pattern/string/
这里pattern是^\(.*\)\(\n\1\)\+$,现在string是\1。
pattern 可以这样分解:
^\(subpattern1\)\(subpattern2\)\+$
^并$分别匹配行首和行尾。
\(和\)用来括起来,subpattern1这样我们以后可以用特殊数字来引用它\1。
它们也用于封闭,subpattern2以便我们可以使用量词将其重复1次或更多次\+。
subpattern1是.*
.与除换行符以外的任何字符匹配的元字符,并且*是与最后一个字符匹配0、1或更多次的量词。
因此.*匹配任何不包含新行的文本。
subpattern2是\n\1
\n相匹配的新行,\1这是里面的第一个匹配相同的文本相匹配\(,\)在这里是subpattern1。
因此pattern可以这样看:
第(^)行的开头,然后是不包含新行(.*)的任何文本,然后是新行(\n),然后是相同的文本(\1),后两个重复一次或多次(\+),并且最后是($)行的结尾。
无论在哪里pattern匹配(相同行的块),替换命令都将其替换为string此处\1(该行的第一行)。
如果要在不更改文件中任何内容的情况下查看将影响哪些行,可以启用该hlsearch选项并n在命令末尾添加替换标志:
:%s/^\(.*\)\(\n\1\)\+$/\1/n
为了进行更精细的控制,您还可以通过添加c替换标志来更改每个行之前要求确认:
:%s/^\(.*\)\(\n\1\)\+$/\1/c
有关替换命令读取更多的信息:help :s,
用于替代标志:help s_flags,
对各种元字符和量词阅读:help pattern-atoms,
并在VIM正则表达式阅读此。
编辑:通配符通过$在末尾添加a来解决命令中的问题pattern。
而且BloodGain具有相同命令的更短且更易读的版本。
$。否则,它将以与上一行相同的文本开头的行,但还有其他一些尾随字符,来做意外的事情。还要注意,您给出的基本命令在功能上等同于我对的回答:%!uniq,但是高亮和确认标志很好。