PERL:拆分并存储在哈希和打印中

时间:2015-09-01 01:15:50

标签: regex perl split hash

我有一个2.5GB的文件,并希望将内容存储到哈希中。 输入文件有点像这样:

REPORT.TXT
chain_name    number    classification    description

chain_name    number    classification    description

chain_name    number    classification    description

chain_name    number    classification    description

依旧.......

这是我为此编写的代码:

open (my $rept, "< report.txt");
open (o_f, "> output.txt");
my %hash;
while ( my $line1 = <$report_fh>)
{
  chomp $line1;
  (my $chain, my $number, my $classification , my $description) = split / {2,}/, $line1;
  #print o_f ("$chain-------->$description\n");  # for checking whether splitting took place successfully, this works perfectly.
  $hash{$chain} = $description;
}   

# for printing the hash values 
while ( my ($k,$v) = each %hash ) 
{
  print o_f (" $k ===> $v\n");
}

打印的散列都是混乱的(与输入文件中的散列顺序不同)并且在我尝试打印散列时并非所有行都被打印。

我一直在敲我的脑袋,想出这几个小时,需要帮助。

4 个答案:

答案 0 :(得分:4)

哈希显式无序。他们的输出顺序是随机的。这是设计 - 任何时候你依赖哈希排序,然后你做了一些令人讨厌的事情。它最近确实变得更糟(例如,更明显的是你的代码错了)。 Algorithmic Complexity attacks因此,从Perl 5.18开始,效果更加明显。但这并没有改变哈希不是有序的潜在问题,也不应该被认为是。

如果您需要订购的数据,这就是我们拥有数组的原因。你可以:

  • 将您的密钥推入数组以维护“文件顺序”。
  • 使用sort订购输出键。

因此,在您的代码中,您可以这样做:

$hash{$chain} = $description;
push ( @order, $chain ); 

然后打印:

foreach my $key ( @order ) { 
   print "$key => $hash{$key}\n";
}

或者:

foreach my $key ( sort keys %hash ) { 
    print "$key => $hash{$key}\n"; 
}

也许值得查看哈希的slices - 这可以让您提取特定的值序列。

注意:%hash是一个令人讨厌的变量名称。称之为描述性的东西。相信我,没有什么比尝试调试代码更糟糕的了。我建议:

my %description_of;

那么你可以写:

$description_of{$chain} = $description;

答案 1 :(得分:0)

试试这个:

cat report.txt | perl -F'\x20{2,}' -nale 'print $F[0]," ===> ", $F[-1]' > output.txt

\ x20是SPACE,-Fpattern,你不能在模式中使用文字空格。

如果某行仍然没有在output.txt中,您应该向我们展示有关report.txt的更多信息。

在哈希中存储2.5G数据太糟糕了。

答案 2 :(得分:0)

use strict;
use warnings;
use Data::Dumper;

my %hashStore = (); my $cnt = '1';
my $addarry = '1'; my ($iniCnt,@twodimarray,$rings) = "";
while(<DATA>)
{
    my $line = $_; my ($one, $two,$three,$four) = "";
    if($line!~m/^$/)
    {
        $line=~s/^/$cnt\t/; my $nwline = $line;  my $i = '0';
        if($nwline=~m/^([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)\t([^\t]+)/g)
        {
            $twodimarray[$addarry][$i] = $1;
            $i++;
            $twodimarray[$addarry][$i] = $2;
            $i++;
            $twodimarray[$addarry][$i] = $4;
            $i++;
            $rings = $twodimarray[$addarry];
        }
        $cnt++;

        my $keys = $rings->[0];
        my $vals = $rings->[1];
        my $last = $rings->[2];

        $hashStore{$keys}{$vals} = $last;

        #$nwline=~s## my $fulcnt=$&; my $chain=$1; my $desp=$4; chomp($chain); chomp($desp); $hashStore{$chain}=$desp; ($fulcnt); #eg;
    }
}

print Dumper \%hashStore;

__DATA__
chain_name  number1 classification1 description1

chain_name  number2 classification2 description2

chain_name  number3 classification3 description3

chain_name  number4 classification4 description4

答案 3 :(得分:0)

此处无需在内存中存储任何内容。直接从旧文件转到新文件。

sbin