根据 linux/ubuntu 中大型 text/csv 文件中的第一列获取所有重复项的列表

Get list of all duplicates based on first column within large text/csv file in linux/ubuntu

我正在尝试根据我非常大的 text/csv 文件(7+ GB / 100+ 百万行)的第一个 column/index 提取所有重复项。格式是这样的:

foo0:bar0
foo1:bar1
foo2:bar2

第一列是任何小写的 utf-8 字符串,第二列是任何 utf-8 字符串。我已经能够根据第一列和第一列对我的文件进行排序:

sort -t':' -k1,1 filename.txt > output_sorted.txt

我还能够删除所有重复项:

sort -t':' -u -k1,1 filename.txt > output_uniq_sorted.txt

这些操作需要 4-8 分钟。

我现在正尝试根据第一列并且仅根据第一列提取所有重复项,以确保第二列中的所有条目都匹配。

我想我可以用 awk 和这个代码来实现这个:

BEGIN { FS = ":" }
{   
    count[]++;

    if (count[] == 1){
        first[] = [=15=];
    }

    if (count[] == 2){
        print first[];
    }

    if (count[] > 1){
        print [=15=];
    }
}

运行 它与:

awk -f awk.dups input_sorted.txt > output_dup.txt

现在的问题是这需要花费 3 个多小时而且还没有完成。我知道 uniq 可以通过以下方式获取所有重复项:

uniq -D sorted_file.txt > output_dup.txt

问题是指定分隔符并且只使用第一列。我知道 uniq 有一个 -f N 可以跳过第一个 N 字段。有没有办法在不 change/process 我的数据的情况下获得这些结果?是否有其他工具可以完成此操作?我已经将 python + pandas 与 read_csv 一起使用并获取了重复项,但这会导致错误(分段错误)并且效率不高,因为我不必加载所有数据在内存中,因为数据已排序。我有不错的硬件

欢迎提供任何帮助, 谢谢。

下面的解决方案

使用:

awk -F: '{if(p!=){p=; c=0; p0=[=18=]} else c++} c==1{print p0} c'

使用命令 time 我得到以下性能。

real    0m46.058s
user    0m40.352s
sys     0m2.984s

如果您的文件已经排序,您不需要存储超过一行,试试这个

$ awk -F: '{if(p!=){p=; c=0; p0=[=10=]} else c++} c==1{print p0} c' sorted.input

如果你尝试这个,请 post 时间...

我稍微更改了 awk 脚本,因为我无法完全理解上面的 awnser 中发生了什么。

awk -F: '{if(p!=){p=; c=0; p0=[=10=]} else c++} c>=1{if(c==1){print p0;} print [=10=]}' sorted.input > duplicate.entries

我已经测试过,这会产生与上面相同的输出,但可能更容易理解。

{if(p!=){p=; c=0; p0=[=11=]} else c++}

如果行中的第一个标记与之前的不同,我们将保存第一个标记,然后将 c 设置为 0 并将整行保存到 p0 中。如果相同,我们增加 c。

c>=1{if(c==1){print p0;} print [=12=]}

在重复的情况下,我们检查它是否第一次重复。如果是这样,我们打印保存行和当前行,如果不打印当前行。