从flatfile

时间:2016-10-05 16:41:05

标签: arrays perl hash

我正在尝试通过平面文件进行解析,并根据被视为键的某些列聚合一些列。我通过构建数组数据结构的哈希来做到这一点。一旦构建了HoA数据结构,我将再次遍历散列并将内容写入新文件。代码在小数据的情况下工作正常,但是当遇到大数据(~800Mb)时,脚本会因内存不足错误而中断。下面是我的脚本的代码片段。实际上,我将解析一个包含140列的数据。因此每个哈希键都有一个包含100多个元素的数组。

我做了一些研究,并发现了一些帖子,他们建议使用DB_FileDBM::Deep等模块将此数据结构存储到磁盘中,但我在我的代码中使用它并不困难。我觉得他们的用法很难理解。有人可以告诉我什么是处理这个问题的最佳方法。

use strict;
use warnings;
use Data::Dumper;
my $header = <DATA>;
chomp $header;
my @ColHeader = split /\|/,$header;
my $j=0;
my %ColPos = map {$_ => $j++} @ColHeader;
print Dumper \%ColPos;
my %hash;
my @KeyCols = qw(col1 col2 col3);
my @AggrCols = qw(col4 col5 col6 col7 col9);

while(my $line = <DATA>) {
    chomp $line;
    my @rowData = split /\|/,$line;
    my $Key = join ':',@rowData[@ColPos{@KeyCols}];
    my $i=0;
    foreach my $k(@rowData[@ColPos{@AggrCols}]) {
        $hash{$Key}[$i++] += $k;    
    }


}


__DATA__
col1|col2|col3|col4|col5|col6|col7|col8|col9|col10|col11
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
a1|a2|a3|1|2|3|4|somedata|1|text|alpha
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
b1|b2|b3|1|2|3|4|somedata|1|text|alpha
a1|a2|a3|1|2|3|4|somedata|1|text|alpha

1 个答案:

答案 0 :(得分:1)

这可能是一个解决方案,但我并不熟悉DBD::CSV模块。这种方法可以避免将数据加载到散列中,并且不应存在内存不足问题。您必须安装DBD :: CSV和DBI

(注意我在测试时输入了另外一行数据, a1 | a2 | a4 | 1 | 2 | 3 | 4 | somedata | 1 | text | alpha 。)

#!/usr/bin/perl
use strict;
use warnings;
use DBI;

my $dbh = DBI->connect("DBI:CSV:f_dir=.");
$dbh->{'csv_tables'}->{'data'} = { 'file' => 'j1.txt', 'csv_sep_char' => "|"};

my @KeyCols = qw(col1 col2 col3);
my @AggrCols = qw(col4 col5 col6 col7 col9);
my @sums = map "sum($_)", @AggrCols;

my $sql;
{
    local $" = ',';
    $sql = <<SQL;
    select @KeyCols, @sums
    from data
    group by @KeyCols
SQL
}

my $sth = $dbh->prepare( $sql );
$sth->execute;

while ( my $row = $sth->fetchrow_arrayref ) {
    print "@$row\n";
}

__END__
*** contents j1.txt

col1|col2|col3|col4|col5|col6|col7|col8|col9|col10|col11
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
a1|a2|a3|1|2|3|4|somedata|1|text|alpha
c1|c2|c3|1|2|3|4|somedata|1|text|alpha
b1|b2|b3|1|2|3|4|somedata|1|text|alpha
a1|a2|a3|1|2|3|4|somedata|1|text|alpha
a1|a2|a4|1|2|3|4|somedata|1|text|alpha

这是因为:

c1 c2 c3 3 6 9 12 3
b1 b2 b3 1 2 3 4 1
a1 a2 a3 2 4 6 8 2
a1 a2 a4 1 2 3 4 1

您希望输出的输出由您决定。对于此示例,数据是空格分隔的,可能不是您想要的。

更新:我对内存使用可能有误,特别是对于这个大文件。它可能会耗尽内存。对不起,如果这不是帮助。