Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

reading file in Hash

by Anonymous Monk
on May 07, 2009 at 05:22 UTC ( #762490=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks, I have a file which have some data in tabular format as follows :
1 2 3 a p x b q y c r z
now, i want to read it in an hash such that i get :
{1 => [a,b,c], 2 => [p,q,r], 3 => [x,y,z] }
but, the number of variable in row and columb in the file will vary. Can any one help me with this... Thanks.

Replies are listed 'Best First'.
Re: reading file in Hash
by planetscape (Chancellor) on May 07, 2009 at 06:14 UTC

    One of the best discussions of complex data structures, and how to access their innards, is to be found in Chapter 3. References and complex data structures of perlinter.pdf, available from Perl Training Australia. The OP would probably want the most current version of the course notes, though, which have been reworked into progperl.pdf, available from the same page noted above.


Re: reading file in Hash
by ig (Vicar) on May 07, 2009 at 05:35 UTC

    There is some very good introductory material in Getting Started with Perl, and pointers to many resources both on-line and books. If you start at the beginning of one of the books or on-line tutorials, it should not take you long to learn what you need to solve this problem.

Re: reading file in Hash
by jwkrahn (Monsignor) on May 07, 2009 at 07:06 UTC
    $ perl -e' use Data::Dumper; my $data = <<DATA; 1 2 3 a p x b q y c r z DATA open my $FH, "<", \$data or die "Cannot open \$data $!"; my ( @headers, %hash ); while ( <$FH> ) { my @fields = split; if ( $. == 1 ) { @hash{ @headers = @fields } = (); } else { push @{ $hash{ $_ } }, shift @fields for @headers; } } print Dumper \%hash; ' $VAR1 = { '1' => [ 'a', 'b', 'c' ], '3' => [ 'x', 'y', 'z' ], '2' => [ 'p', 'q', 'r' ] };
Re: reading file in Hash
by targetsmart (Curate) on May 07, 2009 at 06:33 UTC
    open the file
    use while to read contents of the file
    split the line you read
    if it is going to be only running number you can use arrays of arrays, see perldsc
    if the first line doesn't contain only numbers it is good to use hashes, in which case you have to explicitly maintain the column to key map in a separate hash
    other than the first line all the remaining data seems to be the values, so use push to populate the sub arrays.

    hope this helps

    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
Re: reading file in Hash
by vinoth.ree (Monsignor) on May 07, 2009 at 08:04 UTC

    Do like this way also

    use strict; use warnings; use Data::Dumper; open FH, "file", or die "Cannot open \$data $!"; my ( @headers, %hash, @arr ); while(<FH>){ chomp; if($.==1){ @arr=split /\s+/,$_; foreach(@arr){ $hash{$_}=[]; } } else{ my @temp=split /\s+/,$_; my $i=0; foreach(@temp){ push @{$hash{$arr[$i++]}},$_; } } } print Dumper \%hash;
Re: reading file in Hash
by perliff (Monk) on May 07, 2009 at 14:44 UTC
    You can also try to use the Data::CTable module. Here's a one way you can do to get the final data structure you need. You should read more module documentation for the Data::CTable module if you need more functions to access/modify the data.
    #!/usr/bin/perl use strict; use Data::Dumper; use Data::CTable; my $table = Data::CTable->new("data.txt"); $table->clean_ws(); # a bit of a clean up my $fields = $table->fieldlist_all(); my %final_hash; foreach my $col ( @$fields ) { $final_hash{$col} = $table->{$col} ; ## Get a column you know + exists } print Dumper \%final_hash;
    gives the output...
    $VAR1 = { '1' => [ 'a', 'b', 'c' ], '3' => [ 'x', 'y', 'z' ], '2' => [ 'p', 'q', 'r' ] };



    "with perl on my side"

Re: reading file in Hash
by codeacrobat (Chaplain) on May 07, 2009 at 21:25 UTC
    lets golf.
    perl -e 'print<<EOF 1 2 3 a b c d e f g h i EOF ' | perl -MData::Dumper -lane '1==$. and @h=@F and next;my $i; push @ +{$v{$h[$i++]}},$_ for @F}{print Dumper(\%v)'

      did you say "golf" and "my" in the same sentence?
Re: reading file in Hash
by bichonfrise74 (Vicar) on May 07, 2009 at 16:16 UTC
    Try something like this...
    #!/usr/bin/perl use strict; use Data::Dumper; my %HoA; my $count = 0; while (<DATA>) { my @arrays = split; $HoA{$count} =[ @arrays ]; $count++; } print Dumper(\%HoA); __DATA__ 1 2 3 a p x b q y c r z

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://762490]
Approved by targetsmart
Front-paged by targetsmart
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2021-10-20 22:08 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (82 votes). Check out past polls.