在Perl中一次解析多个文件

时间:2010-12-31 14:23:06

标签: perl performance parsing file memory-management

我有一个大型数据集(约90GB)可供使用。每天每小时都有数据文件(制表符分隔),我需要在整个数据集中执行操作。例如,获取其中一列中给出的操作系统份额。我尝试将所有文​​件合并到一个巨大的文件中并执行简单的计数操作,但它对于服务器内存来说太大了。

所以,我想我需要一次执行每个文件的操作,然后最后加起来。我是perl的新手,对性能问题特别天真。在这种情况下如何进行此类操作。

作为示例,文件的两列是。

ID      OS
1       Windows
2       Linux
3       Windows
4       Windows

让我们做一些简单的事情,计算数据集中操作系统的份额。因此,每个.txt文件都有数百万行,并且有很多这样的文件。什么是最有效的操作整个文件的方法。

2 个答案:

答案 0 :(得分:3)

除非您将整个文件读入内存,否则我不明白为什么文件大小应该是个问题。

my %osHash;

while (<>)
{
   my ($id, $os) = split("\t", $_);
   if (!exists($osHash{$os}))
   {
      $osHash{$os} = 0;
   }
   $osHash{$os}++;
}

foreach my $key (sort(keys(%osHash)))
{
   print "$key : ", $osHash{$key}, "\n";
}

答案 1 :(得分:1)

虽然保罗·汤姆林的答案涉及填写哈希值,但这里打开文件是相同的:

use strict;
use warnings;
use 5.010;
use autodie;

my @files = map { "file$_.txt" } 1..10;

my %os_count;

for my $file (@files) {
    open my $fh, '<', $file;
    while (<$file>) {
        my ($id, $os) = split /\t/;
        ... #Do something with %os_count and $id/$os here.
    }
}

我们只是串行打开每个文件 - 由于您需要读取所有文件中的所有行,因此您无法做更多的事情。一旦你有了哈希,你可以将它存储在某个地方并在程序启动时加载它,然后跳过所有行直到你读到的最后一行,或者只是seek那里,如果你的记录不喜欢,它看起来不像它