【发布时间】: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