1

我有两个看起来像的文本文件:

col1 primary col3 col4
blah 1       blah  4
1    2       5     6
...

colA primary colC colD
1    1       7    27
foo  2       11   13

我想将它们合并到一个更宽的表中,例如:

primary  col1 col3 col4 colA colC colD
1        blah blah 4    a    7    27
2        1    5    6    foo  11   13

我对 Perl 很陌生,所以我不确定最好的方法是什么。请注意,列顺序无关紧要,并且有几百万行。不幸的是,我的文件也没有排序。

我目前的计划,除非有替代方案:对于其中一个文件中的给定行,扫描另一个文件以查找匹配的行,并根据需要将它们都附加到新文件中。不过,这听起来很慢而且很麻烦。

谢谢!

4

1 回答 1

-1
  • 解决方案 1。

    1. 使用标准的 CPAN 分隔文件解析器逐行读取两个文件中较小的一个,就像TXT::CSV_XS解析列一样。

    2. 将每条记录(作为列的数组引用)保存在哈希中,合并列是哈希键

    3. 完成后,使用标准 CPAN 分隔文件解析器逐行读取两个文件中较大的一个,TXT::CSV_XS以解析列。

    4. 对于每条记录,找到连接键字段,从存储文件#1 的数据的哈希中找到匹配的记录,根据需要合并 2 条记录,然后打印。

    注意:这是非常占用内存的,因为整个较小的文件将存在于内存中,但不需要您读取其中一个文件数百万次。


  • 解决方案 2。

    1. 将 file1(使用 Unixsort或一些简单的 Perl 代码)排序为“file1.sorted”

    2. 将 file2(使用 Unixsort或一些简单的 Perl 代码)排序为“file2.sorted”

    3. 打开两个文件进行阅读。循环直到两者都被完全读取:

      • 如果该文件的缓冲区为空(缓冲区只是一个包含下一条记录的变量),则将每个文件的 1 行读入缓冲区。

      • 比较两行之间的索引。

      • 如果 index1 < index2,将 file1 的记录写入输出(不合并)并清空 buffer1。重复步骤 3

      • 如果 index1 > index2,将 file2 的记录写入输出(不合并)并清空 buffer2。重复。

      • 如果index1 == index2,合并2条记录,将合并后的记录写入输出并清空两个缓冲区(假设连接索引列是唯一的,如果不是唯一的,这一步比较复杂)。

    注意:这不需要您将整个文件保存在内存中,除了对文件进行排序(如果需要,可以以内存受限的方式完成)。

于 2013-04-08T20:37:54.403 回答