使用大量替换对在文本文件中执行大量替换

时间:2009-04-15 16:10:37

标签: text sed large-files replace

假设:

  • 文件a.txt包含数百万行(比如每行一句)(2.6 GB!
  • 文件b.txt包含830k行,成对[word1] [word2]

问题:

如何在巨大的文本文件中为每个830k元组(w1,w2)中的每个word1执行最有效的替换?

像sed,perl,python等天真的方法需要数周才能完成。是否存在(可能基于并行化)方法来执行替换负载?

5 个答案:

答案 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语句

完成后,将第一个表格读回文件