您如何标记缓冲区中与其他行完全相同的所有行?通过标记它们,我的意思是突出显示它们或添加角色或其他东西。我想保留缓冲区中行的顺序。
之前:
foo
bar
foo
baz
后:
foo*
bar
foo*
baz
答案 0 :(得分:77)
作为一个前线:
:syn clear Repeat | g/^\(.*\)\n\ze\%(.*\n\)*\1$/exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' | nohlsearch
这使用Repeat
组突出显示重复的行。
打破它:
syn clear Repeat
::删除之前发现的所有重复g/^\(.*\)\n\ze\%(.*\n\)*\1$/
::对于稍后在文件中重复的任何行
^\(.*\)\n
::一个完整的行\ze
::匹配结束 - 验证模式的其余部分,但不使用匹配的文本(正向前瞻)\%(.*\n\)*
::任意数量的实线\1$
::匹配的完整行的完整行重复exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"'
::将与此匹配的完整行添加到Repeat
语法组
exe
::执行给定的字符串作为ex命令getline('.')
::与g//
escape(..., '".\^$*[]')
::使用反斜杠转义给定的字符以制作合法的正则表达式syn match Repeat "^...$"
::将给定字符串添加到Repeat
语法组nohlsearch
::从g//
贾斯汀的非正则表达式方法可能更快:
function! HighlightRepeats() range
let lineCounts = {}
let lineNum = a:firstline
while lineNum <= a:lastline
let lineText = getline(lineNum)
if lineText != ""
let lineCounts[lineText] = (has_key(lineCounts, lineText) ? lineCounts[lineText] : 0) + 1
endif
let lineNum = lineNum + 1
endwhile
exe 'syn clear Repeat'
for lineText in keys(lineCounts)
if lineCounts[lineText] >= 2
exe 'syn match Repeat "^' . escape(lineText, '".\^$*[]') . '$"'
endif
endfor
endfunction
command! -range=% HighlightRepeats <line1>,<line2>call HighlightRepeats()
答案 1 :(得分:33)
上述答案都不适合我,所以这就是我所做的:
:sort
:g/^\(.*\)$\n\1$/p
答案 2 :(得分:6)
:sort
并将其保存在file1
。:sort u
并将其保存在file2
。gvimdiff
或tkdiff
这两个文件。答案 3 :(得分:3)
为什么不使用:
V*
在正常模式下。
它只搜索当前行的所有匹配项,从而突出显示它们(如果设置已启用,我认为这是默认设置) 此外,您可以使用
n
浏览比赛
答案 4 :(得分:2)
运行列表一次,制作每个字符串的映射以及发生的次数。再次遍历它,并将*附加到地图中值大于1的任何字符串。
答案 5 :(得分:2)
尝试:
:%s:^\(.\+\)\n\1:\1*\r\1:
希望这有效。
更新:下次尝试。
:%s:^\(.\+\)$\(\_.\+\)^\1$:\1\r\2\r\1*: