【问题标题】:Get list of all duplicates based on first column within large text/csv file in linux/ubuntu根据 linux/ubuntu 中的大文本/csv 文件中的第一列获取所有重复项的列表
【发布时间】:2016-11-03 01:02:19
【问题描述】:

我正在尝试根据我的超大文本/csv 文件(7+ GB / 100+ 百万行)的第一列/索引提取所有重复项。格式是这样的:

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[$1]++;

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

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

    if (count[$1] > 1){
        print $0;
    }
}

运行它:

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

现在的问题是,这需要花费 3 个小时以上的时间,但尚未完成。我知道uniq 可以通过以下方式获取所有重复项:

uniq -D sorted_file.txt > output_dup.txt

问题在于指定分隔符并且仅使用第一列。我知道uniq 有一个-f N 可以跳过第一个N 字段。有没有办法获得这些结果而无需更改/处理我的数据?有没有其他工具可以做到这一点?我已经将 python + pandas 与 read_csv 一起使用并获取了重复项,但这会导致错误(分段错误),而且效率不高,因为我不必将所有数据加载到内存中,因为数据已排序。我有不错的硬件

  • i7-4700HQ
  • 16GB 内存
  • 256GB ssd 三星 850 pro

欢迎任何可以提供帮助的东西, 谢谢。

下面的解决方案

使用:

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

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

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

【问题讨论】:

  • 试试awk -F: 'seen[$1] == 1{print pl} seen[$1]++{print} {pl=$0}' input_sorted.txt > output_dup.txt

标签: linux csv awk ubuntu-16.04 uniq


【解决方案1】:

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

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

如果您尝试这样做,请发布时间...

【讨论】:

  • 嘿,非常感谢,这非常好。使用“时间”,实际 0m46.058s,用户 0m40.352s,系统 0m2.984s
【解决方案2】:

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

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

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

{if(p!=$1){p=$1; c=0; p0=$0} else c++}

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

c>=1{if(c==1){print p0;} print $0}

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

【讨论】:

    猜你喜欢
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多