Bash 从非常大的文本文件中删除重复对
我有一个非常大的文本文件(很少GB),其格式如下:Bash 从非常大的文本文件中删除重复对,bash,perl,awk,Bash,Perl,Awk,我有一个非常大的文本文件(很少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 perl-i~-lane'print if$F[
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
perl-i~-lane'print if$F[0]<$F[1]”文件
对于每个值,对硬盘上的文件执行二进制搜索,而不将其加载到内存中。如果看到副本,请将其删除。然后执行最后一步,删除两个或多个\n
可能的解决方案的所有实例:
- 扫描文件
- 对于第二个值小于第一个值的任何对,交换两个数字
- 按第一个数字再按第二个数字对这些对进行排序
- 删除重复项
perl-lane'
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
结束{
打印排序{$a$b}键%h;
}
$key=$F[0]<$F[1]?“$F[0]$F[1]”:“$F[1]$F[0]”;
$h{$key}=“”;
'file.txt
解释:
$key
$hash{$key}
定义为nothingUnix
重定向来创建一个新文件。这里有一个通用的O(n)算法,可以在一个过程中完成此操作(无需循环或排序):
- 查看这双鞋是否已经在您的黑名单中
- 如果是这样,忽略它
- 如果没有,请将其附加到结果文件中;并将交换后的值添加到黑名单中(例如,如果您刚刚将“34”和“43”读到黑名单中)
这需要O(n)个时间来运行,并且黑名单需要O(n)个存储。(如果您将文件作为r/w进行操作以在检查黑名单时删除行,则不会对结果进行额外存储)考虑到
12
和21
相同,是否要删除重复项
< 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
文件输出
这可以处理任意大的文件。不确定这是否有效/是否有用
awk '{ if ($2 > $1) print; else print $2, $1 }' hugetext | sort -nu -O hugetext
我不明白:你有重复的配对,你已经删除了重复的。。。这怎么可能?!你能解释一下吗?@ouki他的意思是他有1,2,然后是2,1,如果有必要,你能重新排序列表吗?如果是这样的话,我有一个解决方案。在第一次排序和删除文件中的DUP之前,如果第一个数字>第二个数字,您不能颠倒顺序吗?@user1297220,没有
24
,是否可以获得42
?如果是,应该输出什么?他可能认为12
等同于21
,如果出现12
,那么21
也不应该出现。至少我是这样理解这个问题的。也许OP可以澄清一下。不,有很多对像and,我想删除它,我的代码就是这样做的。问题是您没有指定当您有1444122而没有1221444时应该发生什么。您没有指定任何新的内容。请澄清。@ikegami您的代码不会接受一个具有单个值{4,1}的文件而不输出任何内容吗?@platoali如果这解决了您的问题,请接受它作为答案。如何做?请你说得更具体一点好吗?这是个不错的主意,假设你们两人都很整齐。如果你有{1,2}你可以翻转它{2,1}用二进制搜索这个值,如果你找到它,就删除它。但这需要大量的磁盘查找。@Alan:如果OP没有内存将文件加载到内存中,我看不到一个不需要大量磁盘读写的解决方案。@ninjagecko我同意,我认为您可能有最好的方法,需要多少内存?;-)您是否需要将黑名单存储在内存中,这样做会比在磁盘上使用N^2循环结构更好?为了减少内存使用量,您只能存储$small,$more对,然后在比较之前将所有对转换为$small,$more格式。考虑到得分最高的答案,您可以使用awk'$1@Bernhard,我知道你的意思。但是OP说,“……这是行不通的,因为这对是不对称的”。不能保证它总是对称的。这将在内存中产生一个非常大的散列。当内存耗尽时,进程将被终止。我无法在内存中加载整个数据。“我无法加载整个文件并在值之间循环。”--OP@ninjagecko他不需要,他只需要一次扫描一行,听起来他已经能够排序和删除重复项了。我相信他的意思是,他不能将整个文件存储在内存中,以便更容易地检查重复的文件,但他如何在不将整个文件读入内存的情况下对文件进行排序?