2008-12-08 34 views
87

Mam plik tekstowy, który zawiera długą listę wpisów (po jednym w każdym wierszu). Niektóre z nich są duplikatami i chciałbym wiedzieć, czy jest możliwe (i jeśli tak, jak) usunąć wszelkie duplikaty. Jestem zainteresowany zrobieniem tego z poziomu vi/vim, jeśli to możliwe.Usuwanie duplikatów wierszy w vi?

+1

Wygląda jak duplikat http://stackoverflow.com/questions/746689/unix-tool-to-remove-duplicate-lines-from-a-file –

+3

Ten ma 1 rok; ten ma 10 miesięcy. Więc na odwrót. – Sydius

+0

@ Konsensus Sydiusa ma teraz na celu ustalenie priorytetu pozyskania (które również masz więcej): http://meta.stackexchange.com/questions/147643/?hl=pl&hl=pl-może--wprowadzić-do-close-a-duplicate-question-even -choć-to-dużo-now-i-ha I to nie są duplikaty, o których nie wspomina się Vima :-) –

Odpowiedz

179

Jeśli jesteś OK z sortowania pliku, można użyć:

:sort u 
+1

Sortowanie jest dopuszczalne, a to rozwiązało problem. Dzięki! – Sydius

+1

To jest takie piękne. Dzięki! – Shrayas

+0

Jeśli sortowanie jest niedopuszczalne, użyj '':%! Uniq'', aby usunąć zduplikowane wpisy bez sortowania pliku. – cryptic0

20

Spróbuj tego:
:%s/^\(.*\)\n\1$/\1/

Wykonaj kopię choć przed spróbować. Jest nietestowany.

+7

to działa. następnym razem, przetestuj to! – hop

+1

@hop Dzięki za przetestowanie go dla mnie. Nie miałem wówczas dostępu do vima. – Sean

+2

to pokazuje wszystkie duplikaty dla mnie, ale nie usuwa, czy brakuje mi tu kroku? – ak85

1

Wybierz linie w trybie Visual linii (Przesunięcie + v), następnie :!uniq. To tylko złapie duplikaty, które przychodzą jedna po drugiej.

+1

Należy zauważyć, że działa to tylko na komputerach z zainstalowanym programem uniq, tj. Linux, Mac, Freebsd itp. – anteatersa

+0

To będzie najlepsza odpowiedź dla tych, którzy nie potrzebują sortowania. A jeśli jesteś użytkownikiem systemu Windows, rozważ wypróbowanie Cygwin lub MSYS. –

0

Chciałbym użyć !}uniq, ale działa to tylko wtedy, gdy nie ma pustych linii.

Dla każdej linii w pliku użyj: :1,$!uniq.

4

Chciałbym połączyć dwa z powyższych odpowiedzi:

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

1G 
!Gsort 
1G 
!Guniq 

Jeśli byłeś ciekaw ilu zduplikowane wiersze zostały usunięte, użyj sterowania-G przed i po, aby sprawdzić liczbę linii obecne w bufor.

+1

sort -u == sort | uniq –

+1

'' uniq 'nie jest rozpoznawany jako polecenie wewnętrzne lub zewnętrzne, program operacyjny lub plik wsadowy. " – hippietrail

0

Odnośnie sposobu implementacji Uniq w VimL, ​​wyszukaj Uniq w postaci plugin I'm maintaining. Zobaczysz różne sposoby jego implementacji, które zostały podane na liście mailingowej Vim.

W przeciwnym razie, :sort u jest rzeczywiście drogą do zrobienia.

4
g/^\(.*\)$\n\1/d 

Działa u mnie w systemie Windows. Linie muszą być najpierw posortowane.

+1

Spowoduje to usunięcie linii następującej po linii, która jest jego przedrostkiem:' aaaa' po której następuje 'aaaabb' usunie' aaaa "błędnie. – hippietrail

14

z linii poleceń po prostu zrobić:

sort file | uniq > file.new 
+0

To bardzo przydatne dla mnie ogromny plik. Dzięki! – Rafid

+0

Nie można uzyskać akceptowanej odpowiedzi, ponieważ ': sort u' wisiało na moim dużym pliku. To działało bardzo szybko i idealnie. Dziękuję Ci! – Tgsmith61591

+1

'' uniq 'nie jest rozpoznawany jako polecenie wewnętrzne lub zewnętrzne, program operacyjny lub plik wsadowy. " – hippietrail

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

lub

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

to jest moja odpowiedź dla Ciebie, to może usunąć wiele zduplikowanych wierszy i zachować tylko jeden nie usunąć!

3

awk '!x[$0]++' yourfile.txt jeśli chcesz zachować kolejność (tzn. Sortowanie jest niedopuszczalne). Aby wywołać go z vim, można użyć :!.

+1

To jest piękne! Brak konieczności sortowania to * dokładnie * to, czego szukałem! – Cometsong