根据 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 一起使用并获取了重复项,但这会导致错误(分段错误)并且效率不高,因为我不必加载所有数据在内存中,因为数据已排序。我有不错的硬件
- i7-4700HQ
- 16GB 内存
- 256GB 固态硬盘三星 850 pro
欢迎提供任何帮助,
谢谢。
下面的解决方案
使用:
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=]}
在重复的情况下,我们检查它是否第一次重复。如果是这样,我们打印保存行和当前行,如果不打印当前行。
我正在尝试根据我非常大的 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 一起使用并获取了重复项,但这会导致错误(分段错误)并且效率不高,因为我不必加载所有数据在内存中,因为数据已排序。我有不错的硬件
- i7-4700HQ
- 16GB 内存
- 256GB 固态硬盘三星 850 pro
欢迎提供任何帮助, 谢谢。
下面的解决方案
使用:
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=]}
在重复的情况下,我们检查它是否第一次重复。如果是这样,我们打印保存行和当前行,如果不打印当前行。