假设:
a.txt
包含数百万行(比如每行一句)(2.6 GB!b.txt
包含830k行,成对[word1] [word2]
问题:
如何在巨大的文本文件中为每个830k元组(w1,w2)中的每个word1执行最有效的替换?
像sed,perl,python等天真的方法需要数周才能完成。是否存在(可能基于并行化)方法来执行替换负载?
答案 0 :(得分:5)
我会在python中完成它,但是如果你正确算法,任何其他语言都可以完成这项工作。 整个技巧是将字对(文件b.txt)保存在内存中,并在一次通过中检查大文件。由于I / O操作比从RAM读取慢得多,因此该方法的性能将为O(file1)+ O(file2)
在伪代码中:
myMap = {}
for line in fileB:
myMap[1st word of line] = 2nd word of line
for line in fileA
for word in line
if myMap contains word
replace word with myMap[word]
我想这是你能得到的最快的。
答案 1 :(得分:0)
将文件拆分为更小的块。除了在内存或磁盘上移位之外,你可能会占用大量的内存空间。
这类似于在字符串数组而不是单个字符串上连接/替换它的速度要快得多。
唯一的技巧是确保你在文件中放置中断的地方不是一个很好的匹配,这是相对微不足道的。事实上,如果你可以通过线路来做,那就更好了,不需要检查匹配。
我也觉得很奇怪PERL周需要。有一些轶事证据表明它可以在不到一个小时内处理:
事实上,他们在第二个链接中谈论1gb文件需要2分钟。
我不会怀疑替换操作应该比文件的复制操作花费更长的时间,毕竟,它只是拾取文件的块并在移动时替换一些位。它应该能够在复制速度附近快速替换它们(因为它们已经在内存中)
答案 2 :(得分:0)
按单词对查找/替换对列表进行排序,找到[word1]
然后通读文件,将每一行拆分为单词,并查找要替换的单词列表中的每个单词(使用像二进制搜索一样高效的单词)。
应该可以实现。
答案 3 :(得分:0)
我同意idrosid的答案,只需将对加载到内存中,然后在文件上流式传输。如果你真的有很多数据(大量的Gb)并且你没有机器资源来尽可能快地完成这项工作,亚马逊的新Elastic Hadoop服务将是一个很好的解决方案。一旦你有一个简单的可执行文件可以处理小文件,使用Hadoop的Map Reduce框架就可以很容易地扩展到大量的数据。
答案 4 :(得分:-1)
我在SQL中这样做。
创建一个包含两列(dataline,sequence)的表,并将a.txt放入其中(每个表行一行)
然后创建第二个表,再次使用两列(word1和word2)并将b.txt读入其中(同样,每个表行一行)
根据table2生成更新table1的更新语句
运行sql语句
完成后,将第一个表格读回文件