8

我必须通过组合两个不同的文件来处理一些数据。它们都有两列可以形成一个主键,我可以用它来并排匹配它们。有问题的文件很大(大约 5GB,有 2000 万行),所以我需要一个高效的代码。我将如何在 Perl 中执行此操作?

我举个例子:

如果文件 A 包含列

id, name, lastname, dob, school

文件 B 包含列

address, id, postcode, dob, email

我需要通过匹配这两个文件中的iddob来加入这两个文件,以获得一个包含以下列的输出文件:

 id, name, lastname, dob, school, address, postcode, email
4

6 回答 6

7

想我会创建一个新的 mysql/sqlite/whatever DB 并插入行。应该是大约 20 行 perl。

当然,这需要轻松访问数据库..

猜猜你也可以按感兴趣的字段对文件进行排序,然后为 file1 中的每一行查找并打印 file2 中的匹配行。

于 2012-01-03T12:53:32.110 回答
2

执行此操作的老式方法是使用系统实用程序按键顺序对两个文件进行排序,然后逐行匹配它们。读取两个文件,如果键匹配输出数据。如果它们不匹配,请使用较小的键读取文件,直到它们匹配。如果文件命中 eof,则将文件的密钥设置为无限高。当两个键都无限高时,您就完成了。

于 2012-01-03T17:09:14.340 回答
0

Also, you can try DBD::AnyData

于 2012-01-09T12:41:55.267 回答
0

或者,仔细阅读这篇不错的Techrepublic文章——不过,您仍然可能需要 5G 内存。我想知道使用 unix/linux CLI 排序/加入实用程序会带你去哪里,效率方面。只是一个想法。

于 2012-01-03T16:29:54.133 回答
0

我实际上并没有尝试过,但更有创意的解决方案可能是:

  1. 读取每个文件一次,并在唯一的 id+dob 组合及其在文件中的位置之间创建一个映射。使用告诉()
  2. 在 perl 中创建地图
  3. 使用地图和sysread()中的位置从文件中读取实际数据
  4. 将数据写入新文件
于 2012-01-04T10:54:48.063 回答
0

你也可以使用我 3 年前的 CPAN 模块 Set::Relation,它旨在做这样的事情,让你做所有的 SQL 功能,比如在 Perl 中加入。为每个文件创建一个 Set::Relation 对象,然后使用 join() 方法。也就是说,这个模块作为实现将保留你所有的操作数并导致内存,所以它受到你的 RAM 的限制。但是您仍然可以查看其源代码以了解 join() 的工作原理,然后基于它为您的目的实现更高效的版本。

于 2012-01-09T06:10:01.320 回答