У мене є текстовий файл, який містить довгий список записів (по одному у кожному рядку). Деякі з них є дублікатами, і я хотів би знати, чи можна (і якщо так, як) видалити будь-які дублікати. Мені цікаво це робити, якщо можливо, в межах vi / vim.
У мене є текстовий файл, який містить довгий список записів (по одному у кожному рядку). Деякі з них є дублікатами, і я хотів би знати, чи можна (і якщо так, як) видалити будь-які дублікати. Мені цікаво це робити, якщо можливо, в межах vi / vim.
Відповіді:
Якщо ви все в порядку зі сортуванням вашого файлу, ви можете використовувати:
:sort u
:%!uniq
для простого видалення повторюваних записів, не сортуючи файл.
u
Спробуйте це:
:%s/^\(.*\)\(\n\1\)\+$/\1/
Він шукає будь-який рядок, за яким відразу слідує одна чи кілька копій, і замінює його однією копією.
Зробіть копію свого файлу, хоча перш ніж спробувати. Це неперевірено.
З командного рядка просто виконайте:
sort file | uniq > file.new
:sort u
було на моєму великому файлі. Це спрацювало дуже швидко та ідеально. Дякую!
'uniq' is not recognized as an internal or external command, operable program or batch file.
awk '!x[$0]++' yourfile.txt
якщо ви хочете зберегти замовлення (тобто сортування неприйнятне). Для того, щоб викликати його від vim, :!
можна використовувати.
g/^\(.*\)$\n\1/d
Для мене працює у Windows. Лінії потрібно спочатку сортувати.
aaaa
після цього aaaabb
буде видалено aaaa
помилково.
Я б поєднав дві відповіді вище:
go to head of file
sort the whole file
remove duplicate entries with uniq
1G
!Gsort
1G
!Guniq
Якщо вам було цікаво побачити, скільки видалених повторних рядків, використовуйте control-G до і після, щоб перевірити кількість рядків у вашому буфері.
'uniq' is not recognized as an internal or external command, operable program or batch file.
Виберіть лінії у візуально-лінійному режимі ( Shift+ v), потім :!uniq
. Це будуть лише ложі дублікатів, які приходять один за одним.
Щодо того, як Uniq можна реалізувати у VimL, шукайте Uniq в плагіні, який я підтримую . Ви побачите різні способи його реалізації, які були надані у списку розсилки Vim.
В іншому випадку :sort u
це дійсно шлях.
Ця версія видаляє лише повторні рядки, які є суміжними. Я маю на увазі, видаляє лише послідовні повторні рядки. Використовуючи дану карту, функція помічає псування з порожніми рядками. Але якщо змінити REGEX на збіг початку рядка, ^
він також видалить повторювані порожні рядки.
" 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 (для дуже великих файлів), з командного рядка Linux використовує sort і uniq:
sort {file-name} | uniq -u