web-dev-qa-db-fra.com

Supprimer les lignes en double dans vi?

J'ai un fichier texte qui contient une longue liste d'entrées (une sur chaque ligne). Certains d'entre eux sont des doublons, et j'aimerais savoir s'il est possible (et si oui, comment) de supprimer les doublons. Je suis intéressé à le faire depuis vi/vim, si possible.

111
Sydius

Si vous êtes d'accord avec le tri de votre fichier, vous pouvez utiliser:

:sort u
231
Brian Carper

Essaye ça:

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

Il recherche toute ligne immédiatement suivie d'une ou plusieurs copies de lui-même et la remplace par une seule copie.

Faites une copie de votre fichier avant de l'essayer. Ce n'est pas testé.

26
Sean

À partir de la ligne de commande, faites simplement:

sort file | uniq > file.new
20
Kevin

awk '!x[$0]++' yourfile.txt si vous souhaitez conserver l'ordre (c'est-à-dire que le tri n'est pas acceptable). Pour l'invoquer depuis vim, :! peut être utilisé.

7
Rovin Bhandari
g/^\(.*\)$\n\1/d

Fonctionne pour moi sur Windows. Cependant, les lignes doivent d'abord être triées.

6
Bridgey

Je combinerais deux des réponses ci-dessus:

go to head of file
sort the whole file
remove duplicate entries with uniq

1G
!Gsort
1G
!Guniq

Si vous souhaitez voir combien de lignes en double ont été supprimées, utilisez control-G avant et après pour vérifier le nombre de lignes présentes dans votre tampon.

5
Jon DellOro

Sélectionnez les lignes en mode ligne visuelle (Shift+v), puis :!uniq. Cela n'attrapera que les doublons qui se succèdent.

3
derobert

Concernant comment Uniq peut être implémenté dans VimL, ​​recherchez Uniq dans un plugin que je maintiens . Vous verrez différentes façons de l'implémenter qui ont été données sur la liste de diffusion Vim.

Autrement, :sort u est en effet la voie à suivre.

0
Luc Hermitte

Cette version supprime uniquement les lignes répétées contigües. Je veux dire, ne supprime que les lignes répétées consécutives. En utilisant la carte donnée, la fonction note des erreurs avec des lignes vierges. Mais si changez le REGEX pour qu'il corresponde au début de la ligne ^ il supprimera également les lignes vierges en double.

" function to delete duplicate lines
function! DelDuplicatedLines()
    while getline(".") == getline(line(".") - 1)
        exec 'norm! ddk'
    endwhile
    while getline(".") == getline(line(".") + 1)
        exec 'norm! dd'
    endwhile
endfunction
nnoremap <Leader>d :g/./call DelDuplicatedLines()<CR>
0
SergioAraujo
:%s/^\(.*\)\(\n\1\)\+$/\1/gec

ou

:%s/^\(.*\)\(\n\1\)\+$/\1/ge

c'est ma réponse pour vous, il peut supprimer plusieurs lignes en double et n'en garder qu'une seule pas supprimer!

0
cn8341

J'utiliserais !}uniq, mais cela ne fonctionne que s'il n'y a pas de lignes vides.

Pour chaque ligne d'un fichier, utilisez: :1,$!uniq.

0
Chris Dodd

Cela a fonctionné pour moi à la fois .csv et .txt

awk '!seen[$0]++' <filename> > <newFileName>

Explication: La première partie de la commande imprime des lignes uniques et la deuxième partie, c'est-à-dire après la flèche du milieu, consiste à enregistrer la sortie de la première partie.

awk '!seen[$0]++' <filename>

>

<newFileName>

0
paul

Une méthode alternative qui n'utilise pas vi/vim (pour les très gros fichiers), est à partir de la ligne de commande Linux utilisez sort et uniq:

sort {file-name} | uniq -u
0
william-1066