获取基于linux / ubuntu

时间:2016-11-03 01:02:20

标签: linux csv awk ubuntu-16.04 uniq

我正在尝试根据我的非常大的text / csv文件(7+ GB / 100+ Million行)的第一列/索引提取所有重复项。格式如下:

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字段。有没有办法在不更改/处理我的数据的情况下获得这些结果?有没有其他工具可以实现这一目标?我已经使用了read_csv的python + pandas并获得了重复项,但是这会导致错误(分段错误),这是无效的,因为我不需要加载内存中的所有数据,因为数据已经排序。我有不错的硬件

  • i7-4700HQ
  • 16GB ram
  • 256GB ssd samsung 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

1 个答案:

答案 0 :(得分:1)

如果您的文件已经排序,则无需存储多行,请尝试使用

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

如果你试试这个,请发布时间......