2009-08-12 13 views

Respuesta

60

Como ex de una sola línea:

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

Este utiliza el grupo Repeat para resaltar las repetidas líneas.

Descomponiéndola:

  • syn clear Repeat :: eliminar cualquier encontrado previamente repeticiones
  • g/^\(.*\)\n\ze\%(.*\n\)*\1$/ :: para cualquier línea que se repite más adelante en el archivo
    • la expresión regular
      • ^\(.*\)\n :: una línea completa
      • \ze :: final del partido - verificar que el resto del patrón, pero no consumen el texto coincidente (búsqueda positiva hacia delante)
      • \%(.*\n\)* :: cualquier número de líneas completas
      • \1$ :: una repetición de la línea completa emparejado línea completa
    • exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' :: añadir líneas completas que coincidan con este al grupo Repeat sintaxis
      • exe :: ejecutar la cadena dada como un comando ex
      • getline('.') :: el contenido de la línea actual igualada por g//
      • escape(..., '".\^$*[]') :: escapar los caracteres dados con barras invertidas para hacer una expresión regular de fiar
      • syn match Repeat "^...$" :: añadir la cadena dada al grupo Repeat sintaxis
  • nohlsearch :: eliminar destacando de la búsqueda realizada por g//
método no regex

de Justin es probablemente más rápido:

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

¡El método no regex es rapidísimo! muy buen guión, gracias! – Hassek

+0

esto es realmente increíble! – pymarco

+0

no puedo hacer que esto funcione. he puesto la función en mi ~/.vimrc pero cuando ejecuto ": call HighlightRepeats()" recibo un error: Se detectó un error al procesar la función ResaltadoRechazar: línea 10: E28: No se mencionó el nombre del grupo resaltado: Repetir – Daps0l

3

Ejecutar a través de la lista una vez, crea un mapa de cada cuerda y cuántas veces se produce. Vuelva a recorrerlo y agregue su * a cualquier cadena que tenga un valor de más de uno en el mapa.

+2

¿Alguna posibilidad de que podamos obtener algún código? – technomalogical

2

Probar:

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

Espero que esto funcione.

Actualización: próximo intento.

:%s:^\(.\+\)$\(\_.\+\)^\1$:\1\r\2\r\1*: 
+0

Esto solo detectará líneas duplicadas adyacentes, y solo marcará la primera copia, no la segunda. – rampion

+0

Tienes razón. Lo intenté de nuevo. –

3

Por qué no usar:

V* 

en modo normal.

Simplemente busca en todos los partidos de línea actual, destacando así ellos (si el ajuste está habilitado, lo que creo que es el valor por defecto) Además, a continuación, puede utilizar

n 

Para navegar a través de los partidos

+0

El modo visual no admite * de forma predeterminada. Probablemente es una función que tienes en tu .vimrc. Algo como esto: XNO *: cal VisualSearch() / XNO #: cal VisualSearch() ? diversión! s: VisualSearch() let old = @ "| norm! gvy let @/= '\ V'.substitute (escape (@",' \ '),' \ n ',' \\ n ',' g ') let @ "= old endf) – Michael

+0

Arg, el formateo no funciona. Esto es lo que quise decir: http://pastebin.com/f2ee37c92 – Michael

+0

Sí, tienes razón :) – Lonecat

27

Ninguna de las respuestas anteriores dio para mí, así que esto es lo que hago:

  1. Ordenar el archivo con :sort
  2. ejecutar el comando :g/^\(.*\)$\n\1$/p
+0

Gracias. Siento que este es un mejor enfoque. Con esto podemos encontrar líneas duplicadas y también personalizar a la longitud requerida – harsha

1
  1. :sort y guardarlo en file1.
  2. :sort u y guárdelo en file2.
  3. gvimdiff o tkdiff los dos archivos.
Cuestiones relacionadas