我有一个非常大的文本文件(几 GB),其格式如下:
1 2
3 4
3 5
3 6
3 7
3 8
3 9
文件已排序,双行已删除。我想删除重复的对,例如“2 1”、“4 3”相反的顺序。有没有人有任何解决方案可以在资源非常有限的环境中使用 BASH、AWK、perl 或任何类似语言?我无法加载整个文件并在值之间循环。
您想删除第二个数字小于第一个数字的行吗?
perl -i~ -lane'print if $F[0] < $F[1]' file
可能的解决方案:
我仍在考虑在磁盘扫描方面更有效的解决方案,但这是一种基本的幼稚方法
对于每个值,对硬盘驱动器上的文件执行二进制搜索,而不将其加载到内存中。如果看到重复项,请删除它。然后进行最后一次传递,删除两个或更多的所有实例\n
。
不完全确定这是否有效/是否有任何好处...
awk '{ if ($2 > $1) print; else print $2, $1 }' hugetext | sort -nu -O hugetext
你想删除重复考虑1 2
和2 1
是相同的吗?
< file.in \
| perl -lane'print "@F[ $F[0] < $F[1] ? (0,1,0,1) : (1,0,0,1) ]"' \
| sort -n \
| perl -lane'$t="@F[0,1]"; print "@F[2,3]" if $t ne $p; $p=$t;' \
> file.out
这可以处理任意大的文件。
perl -lane '
END{
print for sort {$a<=>$b} keys %h;
}
$key = $F[0] < $F[1] ? "$F[0] $F[1]" : "$F[1] $F[0]";
$h{$key} = "";
' file.txt
说明:
$key
我通过将第一个值和第二个值与空格连接来创建哈希键变量$hash{$key}
无哈希键本质上是唯一的,所以没有重复。
您只需要使用Unix
重定向来创建一个新文件。
这是一个通用的 O(n) 算法,可以在 1 遍中执行此操作(不需要循环或排序):
这需要 O(n) 时间来运行,并且需要 O(n) 存储黑名单。(如果您将文件作为 r/w 操作以在对照黑名单检查行时删除行,则无需额外存储结果)