我认为以下命令应该工作:
:%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
,但是高亮和确认标志很好。