我有一个文本文件,其中包含一长串条目(每行一个)。其中一些是重复的,我想知道是否可以(如果可以,如何)删除任何重复。如果可能的话,我有兴趣在 vi/vim 中执行此操作。
14 回答
如果您可以对文件进行排序,您可以使用:
:sort u
试试这个:
:%s/^\(.*\)\(\n\1\)\+$/\1/
它搜索紧随其后的一个或多个副本的任何行,并将其替换为单个副本。
在您尝试之前复制您的文件。它未经测试。
从命令行只需执行以下操作:
sort file | uniq > file.new
awk '!x[$0]++' yourfile.txt
如果您想保留顺序(即不接受排序)。为了从 vim 调用它,:!
可以使用。
我会结合上面的两个答案:
go to head of file
sort the whole file
remove duplicate entries with uniq
1G
!Gsort
1G
!Guniq
如果您有兴趣查看删除了多少重复行,请在前后使用 control-G 检查缓冲区中存在的行数。
g/^\(.*\)$\n\1/d
在 Windows 上为我工作。不过,必须先对行进行排序。
在视觉线模式 ( Shift+ v) 中选择线条,然后:!uniq
。那只会捕获一个接一个的重复项。
关于如何在 VimL 中实现 Uniq,请在我正在维护的插件中搜索 Uniq 。您将看到 Vim 邮件列表中提供的各种实现方法。
否则,:sort u
确实是要走的路。
如果您不想对整个文件进行排序/uniq,您可以选择要在可视模式下制作 uniq 的行,然后简单地:sort u
:
我会使用!}uniq
,但只有在没有空行的情况下才有效。
对于文件中的每一行,使用::1,$!uniq
.
:%s/^\(.*\)\(\n\1\)\+$/\1/gec
或者
:%s/^\(.*\)\(\n\1\)\+$/\1/ge
这是我给你的答案,它可以删除多个重复的行,只保留一个不删除!
此版本仅删除连续的重复行。我的意思是,只删除连续重复的行。使用给定的地图,该函数确实会混淆空白行。但是,如果更改正则表达式以匹配行首^
,它也会删除重复的空白行。
" 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
这对我.csv
和.txt
awk '!seen[$0]++' <filename> > <newFileName>
说明: 命令的第一部分打印唯一的行,第二部分,即中间箭头之后的部分是保存第一部分的输出。
awk '!seen[$0]++' <filename>
>
<newFileName>