【发布时间】:2009-08-12 18:53:03
【问题描述】:
您将如何标记缓冲区中与其他行完全相同的所有行?通过标记它们,我的意思是突出它们或添加字符或其他东西。我想保留缓冲区中行的顺序。
之前:
foo
bar
foo
baz
之后:
foo*
bar
foo*
baz
【问题讨论】:
标签: vim duplicates
您将如何标记缓冲区中与其他行完全相同的所有行?通过标记它们,我的意思是突出它们或添加字符或其他东西。我想保留缓冲区中行的顺序。
之前:
foo
bar
foo
baz
之后:
foo*
bar
foo*
baz
【问题讨论】:
标签: vim duplicates
作为前单行:
: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// 的搜索中删除突出显示
Justin 的非正则表达式方法可能更快:
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()
【讨论】:
hi link Repeat Statement 添加到您的~/.vimrc。
以上答案都不适合我,所以我就是这样做的:
:sort对文件进行排序
:g/^\(.*\)$\n\1$/p
【讨论】:
g 全局命令(在这种情况下从上到下遍历每一行)^\(.*\)$ 捕获整行...\n 和newline 字符...\1$ 和上一行(到end) 这部分只是检查下一行是否与当前行相同。但是为什么我的 Vim 会突出显示多个单独的事件,p(粘贴)是干什么用的?
p 用于“打印”。实际上你可以删除它,因为它是默认命令。不确定“为什么我的 Vim 会突出显示多个单独的事件”是什么意思。 Vim 应该突出显示/打印重复的行。
vim -u NONE 并打开一个带有结果的拆分窗格。在这种情况下,我理解您所说的 print 是什么意思。我的一个插件用突出显示的行显示了这个imgur.com/a/6Qu8Q65。在我的另一个 Vim 实例上,它没有显示底部拆分,而是仅突出显示行。
:sort 并将其保存在 file1 中。:sort u 并将其保存在 file2 中。gvimdiff 或 tkdiff 这两个文件。【讨论】:
为什么不使用:
V*
在正常模式下。
它只是搜索当前行的所有匹配项,从而突出显示它们(如果启用了该设置,我认为这是默认设置) 此外,您还可以使用
n
浏览比赛
【讨论】:
遍历列表一次,制作每个字符串的映射以及它出现的次数。再次循环遍历它,并将您的 * 附加到映射中值大于 1 的任何字符串。
【讨论】:
试试:
:%s:^\(.\+\)\n\1:\1*\r\1:
希望这行得通。
更新:下次尝试。
:%s:^\(.\+\)$\(\_.\+\)^\1$:\1\r\2\r\1*:
【讨论】: