web-dev-qa-db-fra.com

Comment puis-je marquer / mettre en évidence des lignes en double dans l'éditeur de VI?

Comment procéder pour marquer toutes les lignes dans un tampon qui sont des doublons exacts d'autres lignes? En les marquant, je veux dire les surligner ou ajouter un personnage ou quelque chose. Je souhaite conserver l'ordre des lignes dans le tampon.

Avant:

foo
bar
foo
baz

Après:

foo*
bar
foo*
baz
55
Brian Carper

En tant qu'ex-liner:

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

Cela utilise le groupe Repeat pour mettre en surbrillance les lignes répétées.

Décomposer:

  • syn clear Repeat :: supprimer toutes les répétitions trouvées précédemment
  • g/^\(.*\)\n\ze\%(.*\n\)*\1$/ :: pour toute ligne répétée ultérieurement dans le fichier
    • l'expression régulière
      • ^\(.*\)\n :: une ligne complète
      • \ze :: fin de correspondance - vérifiez le reste du modèle, mais ne consommez pas le texte correspondant (lookahead positif)
      • \%(.*\n\)* :: n'importe quel nombre de lignes complètes
      • \1$ :: une répétition de la ligne complète correspondante
    • exe 'syn match Repeat "^' . escape(getline('.'), '".\^$*[]') . '$"' :: ajoute des lignes complètes qui correspondent à ceci au groupe de syntaxe Repeat
      • exe :: exécute la chaîne donnée comme une commande ex
      • getline('.') :: le contenu de la ligne courante correspondant à g//
      • escape(..., '".\^$*[]') :: échappe les caractères donnés avec des barres obliques inverses pour faire une expression régulière légitime
      • syn match Repeat "^...$" :: ajoute la chaîne donnée au groupe de syntaxe Repeat
  • nohlsearch :: supprimer la surbrillance de la recherche effectuée pour g//

La méthode non regex de Justin est probablement plus rapide:

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()
78
rampion

Aucune des réponses ci-dessus n'a fonctionné pour moi, alors voici ce que je fais:

  1. Triez le fichier à l'aide de :sort
  2. Exécuter la commande :g/^\(.*\)$\n\1$/p
37
Jenny O'Reilly
  1. :sort et enregistrez-le dans file1.
  2. :sort u et enregistrez-le dans file2.
  3. gvimdiff ou tkdiff les deux fichiers.
6
user7989979

Pourquoi ne pas utiliser:

V*

en mode normal.

Il recherche simplement toutes les correspondances de la ligne actuelle, les mettant ainsi en surbrillance (si le paramètre est activé, ce que je pense que c'est la valeur par défaut). En outre, vous pouvez ensuite utiliser

n

Pour parcourir les matchs

3
Lonecat

Essayer:

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

J'espère que cela fonctionne.

Mise à jour: essayez ensuite.

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

Parcourez la liste une fois, faites une carte de chaque chaîne et combien de fois elle se produit. Parcourez-le à nouveau et ajoutez votre * à n'importe quelle chaîne dont la valeur est supérieure à un dans la carte.

2
Justin