获取重复的行并保留文件的其余部分 [大文件50G]

4

我有一个大文件50G,我想要获取其中的重复行剩余部分。我使用了两个命令来获取结果,但这需要很长时间。

sort file.tsv | uniq -d > duplicateList.tsv 
sort file.tsv | uniq -u > clean_List.tsv

从上面可以看到,这个过程重复了两次,我想只使用一个命令并返回两个结果而不使用重复的命令。

注意,我可以使用Linux命令或Python脚本。


2
你尝试过使用 tee 命令吗?它可以将文件内容传输到不同的消费者或文件中。 - albert
是的,我尝试了tee命令,但没有解决我的问题。 - Younes Zaidi
请定义“很长时间”。请详细说明您如何使用tee以及为什么它“无法工作”。请展示一些代表性的TSV文件行。谢谢。 - Mark Setchell
我是指“很长时间”。例如,如果第一个命令需要15分钟,那么该过程将运行两次,我需要运行下一个命令并花费15分钟。我想在名为duplicateList.tsv的文件中保存重复的电子邮件,并在同一操作中将无重复电子邮件保存在名为clean_List.tsv的文件夹中。我的TSV文件格式是一个电子邮件列表,例如aa@email.com - Younes Zaidi
3个回答

0

哈希是迄今为止最快的。以下是用Python实现哈希算法的方法:

name = '/my/big/file'
lines = dict()
dups  = dict()
with open( name ) as f:
    line = line.rstrip()
    for line in f:
        if line in lines:
            dups[ line ] = True
        else:
            lines[ line ] = True
print( 'Duplicate(s)' )
for line in dups:
    print( line )
print( 'Unique(s)' )
for line in lines:
    if line not in dups:
        print( line )

Python字典是作为一个哈希集合实现的。


0

这个可能适用于你(GNU sed),假设文件已经排序:

sed -Ee 'N;/^(.*)\n\1$/!{P;D};:a;$w duplicatesFile' \
     -e '$d;N;/(\n.*)\1$/ba;h;s/.*\n/\n/;x;s/(.*)\n.*/\1/w duplicatesFile' \
     -e 'x;D' file > nonduplicatesFile

概述:重复的内容被写入到“duplicatesFile”文件中,其余内容被写入到重定向到“nonduplicatesFile”的“stdout”中。
首先创建一个两行缓冲区,并对重复行进行模式匹配。如果没有,则将第一行打印到stdout中,然后删除并重复,直到出现重复行为止。
对于重复行,首先处理文件末尾的边缘情况,其中所有剩余行都输出到“duplicatesFile”中,并停止处理。
对于其他情况,将模式空间复制到保持空间中,然后拆分为重复和非重复部分。将重复部分写入“duplicatesFile”,将非重复部分加上换行符,然后使用“D”命令删除换行符,这会导致sed命令重新运行,而不会从“file”中隐式获取下一行。
注意:Sed从来不是最快的解决方案,也许在这种情况下,专门的代码可以提供所需的速度。

0

我认为你正在寻找这个语法:

sort file.tsv > >(uniq -d > duplicateList.tsv) > >(uniq -u > clean_List.tsv)

它将stdout发送到两个命令,因此只会进行一次排序,而另外两个命令则并行执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接