Удаление повторяющихся строк в vi?
-
20-08-2019 - |
Вопрос
У меня есть текстовый файл, который содержит длинный список записей (по одной в каждой строке).Некоторые из них являются дубликатами, и я хотел бы знать, возможно ли (и если да, то как) удалить все дубликаты.Я заинтересован в том, чтобы сделать это из 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>