Вопрос

У меня есть текстовый файл, который содержит длинный список записей (по одной в каждой строке).Некоторые из них являются дубликатами, и я хотел бы знать, возможно ли (и если да, то как) удалить все дубликаты.Я заинтересован в том, чтобы сделать это из vi / vim, если это возможно.

Это было полезно?

Решение

Если вас устраивает сортировка вашего файла, вы можете использовать:

:sort u

Другие советы

Попробуй это:

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

Он выполняет поиск любой строки, за которой непосредственно следует одна или несколько копий самого себя, и заменяет ее единственной копией.

Однако сделайте копию вашего файла, прежде чем пытаться это сделать.Это непроверено.

Из командной строки просто сделайте:

sort file | uniq > file.new

awk '!x[$0]++' yourfile.txt если вы хотите сохранить порядок (т. е. сортировка неприемлема).Для того, чтобы вызвать его из vim, :! может быть использован.

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

Работает у меня в Windows.Однако сначала строки должны быть отсортированы.

Я бы объединил два приведенных выше ответа:

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

1G
!Gsort
1G
!Guniq

Если вам было интересно узнать, сколько повторяющихся строк было удалено, используйте control-G до и после, чтобы проверить количество строк, присутствующих в вашем буфере.

Выберите линии в режиме визуальных линий (Сдвиг+v), затем :!uniq.Это будет ловить только дубликаты, которые приходят один за другим.

Что касается того, как Uniq может быть реализован в VimL, найдите Uniq в плагин, который я поддерживаю.Вы увидите различные способы его реализации, которые были приведены в списке рассылки Vim.

В противном случае, :sort u это действительно тот путь, по которому нужно идти.

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

или

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

это мой ответ для вас, он может удалить несколько повторяющихся строк и не удаляйте только одну!

Я бы использовал !}uniq, но это работает только в том случае, если нет пустых строк.

Для каждой строки в файле используйте: :1,$!uniq.

В этой версии удаляются только повторяющиеся строки, которые являются смежными.Я имею в виду, удаляет только последовательные повторяющиеся строки.Используя данную карту, функция не допускает путаницы с пустыми строками.Но если изменить РЕГУЛЯРНОЕ выражение так, чтобы оно соответствовало началу строки ^ это также удалит дублирующиеся пустые строки.

" 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>

Альтернативный метод, который не использует vi / vim (для очень больших файлов), - использовать sort и uniq в командной строке Linux:

sort {file-name} | uniq -u

Это сработало у меня для обоих .csv и .txt

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

Объяснение: Первая часть команды выводит уникальные строки, а вторая часть, т. е.после средней стрелки нужно сохранить выходные данные первой части.

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

>

<newFileName>

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top