我有两个文本文件,它们应该有很多匹配的行,我想知道文件之间有多少行匹配。问题是这两个文件都很大(一个文件大约 3gb,另一个文件超过 16gb)。所以很明显,使用 read() 或 readlines() 将它们读入系统内存可能会有很大问题。有小费吗?我正在编写的代码基本上只是一个 2 个循环和一个用于比较它们的 if 语句。
3 回答
由于输入文件非常大,如果您关心性能,您应该考虑简单地使用grep -f
. 该-f
选项从文件中读取模式,因此根据您所追求的确切语义,它可能会满足您的需求。你可能也想要这个-x
选项,只接受整行匹配。所以 Python 中的整个事情可能看起来像这样:
child = subprocess.Popen(['grep', '-xf', file1, file2], stdout=subprocess.PIPE)
for line in child.stdout:
print line
为什么不使用unix grep
?如果您希望您的解决方案平台独立,那么此解决方案将不起作用。但是在unix中它可以工作。从您的 python 脚本运行此命令。
grep --fixed-strings --file=file_B file_A > result_file
此外,这个问题似乎是使用 map-reduce 的一个很好的理由。
更新0:阐明。--fixed-strings = Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.
和--file= Obtain patterns from FILE, one per line.
所以我们正在做的是从file_B
匹配的内容中获取模式file_A
,并将fixed-strings
它们视为一系列模式,就像它们在文件中的方式一样。希望这能让它更清楚。
由于您想要匹配行的计数,因此对上面的内容进行了轻微修改,grep
我们得到了计数 -
grep --fixed-strings --file=file_B file_A | wc -l
更新1:你可以这样做。首先逐行浏览每个文件。不要将整个文件读入内存。当您读取一行时,计算该行的 md5 哈希并将其写入另一个文件。当你对这 2 个文件执行此操作时,你会得到 2 个填充了 md5 哈希的新文件。我希望这两个文件的大小比原始文件小得多,因为 md5 是 16 字节,与 i/p 字符串无关。现在您可能可以执行 grep 或其他差异技术,而几乎没有或没有内存问题。– Srikar 3 分钟前 编辑
更新2:(几天后)你能做到吗?table1, table2
在mysql中创建2个表。两者都只有 2 个字段id, data
。将这两个文件逐行插入这两个表中。之后运行查询以查找重复项的数量。您必须浏览这两个文件。那是给定的。我们不能逃避这个事实。现在可以在如何找到 dup 方面进行优化。MySQL 就是这样一种选择。它消除了许多您需要做的事情,例如 RAM 空间、索引创建等。
谢谢大家的意见!但我最终做的事情非常简单。我正在尝试这样的事情,它读入整个文件。
file = open(xxx,"r")
for line in file:
if.....
我最终做的是
for line in open(xxx)
if.....
第二个逐行获取文件。这非常耗时,但我几乎接受了没有什么神奇的方法可以做到这一点,只需要很少的时间:(