Whiteinch has asked for the wisdom of the Perl Monks concerning the following question:

Hi I am really new in Perl and would like to gain more knowledge in here. I have gone through the basic tutorials but I am stuck in parsing a file and storing the data. If there is any help or guidance would be really helpful. My file data is a table that would be something like this:

(DATA 1) (DATA 2)

Column 1 Column 2 Column 3 Column 4

(DATA 3) (DATA 4) (DATA 5) (DATA 6)

There are many table as shown above and each has many rows in it. I would like to save all the data into a hash that would be something like

{DATA 2} = {DATA 1} = {DATA 3} {DATA 4} {DATA 5} {DATA 6}

What I have done so far is as shown below and is far from the right path as I thought.

my $line = $_; if (/^\s*(-\d+\.*\d*),(\d+\.*\d*),(\d+\.*\d*),(\S+),(\S+),(\S+),(\ +S+)$/) { my $data1 = $1; my $data2 = $2; my $data3 = $3; my $data4 = $4; my $data5 = $5; my $data6 = $6; $hash{data2}{data1}{data3} = $data3; $hash{data2}{data1}{data4} = $data4; $hash{data2}{data1}{data5} = $data5; $hash{data2}{data1}{data6} = $data6;
Does this make hash into hashes or I am not in the right path.

Replies are listed 'Best First'.
Re: Parsing a file and storing the data
by AnomalousMonk (Archbishop) on Mar 02, 2018 at 13:53 UTC

    I share Laurent_R's confusion about the structure of your data. Here are some general thoughts.

    Does this make hash into hashes ...
    Why not see for yourself?
    c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dumper; ;; $_ = '-1.23,4...5,6,foo,bar,baz,boff'; ;; my %hash; ;; if (/^\s*(-\d+\.*\d*),(\d+\.*\d*),(\d+\.*\d*),(\S+),(\S+),(\S+),(\S+) +$/) { my $data1 = $1; my $data2 = $2; my $data3 = $3; my $data4 = $4; my $data5 = $5; my $data6 = $6; ;; $hash{data2}{data1}{data3} = $data3; $hash{data2}{data1}{data4} = $data4; $hash{data2}{data1}{data5} = $data5; $hash{data2}{data1}{data6} = $data6; } ;; print Dumper \%hash; " $VAR1 = { 'data2' => { 'data1' => { 'data6' => 'baz', 'data4' => 'foo', 'data3' => '6', 'data5' => 'bar' } } };
    (See the Data::Dumper module, which is core, for more info.) Is this the data structure you expected? Did you perhaps mean to write
        $hash{$data2}{$data1}{$data3} = $data3;
    instead of
        $hash{data2}{data1}{data3} = $data3;
    ($data1 $data2 are unused otherwise)?

    Are you aware that the regex
        /^\s*(-\d+\.*\d*),(\d+\.*\d*),(\d+\.*\d*),(\S+),(\S+),(\S+),(\S+)$/
    has seven capture groups, but you only use six ($data6)? Are you aware that the regex expression  \.* matches zero or more  . (dot) characters (i.e., it matches '.....')?


    Give a man a fish:  <%-{-{-{-<

Re: Parsing a file and storing the data
by poj (Abbot) on Mar 02, 2018 at 16:00 UTC

    Assuming you have one Data 1,2 record for many Data 3,4,5,6 records, you probably want a hash of arrays

    #!/usr/bin/perl use strict; use Data::Dumper; #use Data::Dump 'pp'; my %data = (); my ($key1,$key2); while (<DATA>){ chomp; next unless /\S/; #skip blank lines my @col = split ',',$_; #column1 is $col[0] if (@col == 2){ ($key1,$key2) = @col; } else { push @{ $data{$key2}{$key1}},\@col; } } #print pp \%data; # use Data::Dump if installed print Dumper \%data; __DATA__ 1,1 1,A1,B1,C1,D1 2,A1,B1,C1,D1 3,A1,B1,C1,D1 1,2 1,A2,B2,C2,D2 2,A2,B2,C2,D2 3,A2,B2,C2,D2 1,3 1,A3,B3,C3,D3 2,A3,B3,C3,D3 3,A3,B3,C3,D3
    poj
Re: Parsing a file and storing the data
by Laurent_R (Canon) on Mar 02, 2018 at 08:45 UTC
    Yes, you're building a hash of hashes of hashes (HoHoH).

    But please show an actual data sample (between <code> and </code> tags), because I cannot make any sense of your regex compared to your description of the input data.