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.
Si vous êtes d'accord avec le tri de votre fichier, vous pouvez utiliser:
:sort u
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é.
À partir de la ligne de commande, faites simplement:
sort file | uniq > file.new
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é.
g/^\(.*\)$\n\1/d
Fonctionne pour moi sur Windows. Cependant, les lignes doivent d'abord être triées.
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.
Sélectionnez les lignes en mode ligne visuelle (Shift+v), puis :!uniq
. Cela n'attrapera que les doublons qui se succèdent.
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.
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>
:%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!
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
.
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>
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