标记重复的行

你将如何去标记缓冲区中所有与其他行重复的行? 通过标记它们,我的意思是突出显示它们或添加一个字符或其他东西。 我想保留缓冲区中的行的顺序。

之前:

foo bar foo baz 

后:

 foo* bar foo* baz 

作为一个前线:

 :syn clear Repeat | g/^\(.*\)\n\ze\%(.*\n\)*\1$/exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' | nohlsearch 

这将使用“ Repeat组来突出显示重复的行。

打破它:

  • syn clear Repeat :删除以前发现的任何重复
  • g/^\(.*\)\n\ze\%(.*\n\)*\1$/ ::对于稍后在文件中重复的任何行
    • 正则expression式
      • ^\(.*\)\n ::一整行
      • \ze ::匹配结束 – validation模式的其余部分,但不要使用匹配的文本(正向查找)
      • \%(.*\n\)* :任意数量的全部行
      • \1$ ::匹配整行的全行重复
    • exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' ::将与此匹配的完整行添加到Repeat语法组
      • exe ::执行给定的string作为ex命令
      • getline('.') ::当前行匹配的内容g//
      • escape(..., '".\^$*[]') ::使用反斜杠转义给定的字符以生成合法的正则expression式
      • syn match Repeat "^...$" ::将给定的string添加到Repeat语法组
  • nohlsearch ::从search结果中删除突出显示g//

贾斯汀的非正则expression式可能更快:

 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. 对文件进行:sort
  2. 执行命令:g/^\(.*\)$\n\1$/p

遍历列表一次,制作每个string的映射以及它发生的次数。 再次循环,并将*附加到地图中具有多个值的string中。

为什么不使用:

 V* 

在正常模式下。

它只是search当前行的所有匹配,从而突出显示它们(如果启用设置,我认为这是默认)此外,您可以使用

 n 

浏览比赛

尝试:

 :%s:^\(.\+\)\n\1:\1*\r\1: 

希望这个作品。

更新:下次尝试。

 :%s:^\(.\+\)$\(\_.\+\)^\1$:\1\r\2\r\1*: 
  1. :sort并保存在file1
  2. :sort u并保存在file2
  3. gvimdiff或者tkdiff这两个文件。