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

Good afternoon ladies and gents (although I've got a feeling I'm speaking to mostly gents. I've got a file that I need to read into a hash line by line, the file in the form of:
Data_Type:1234567890 data data data data data Data_Type:1237834810 data data data data data
after the inital key, there is a tab, followed by multiple descriptions...lengths and number of them vary again separated by tabs. However I only want to split them once into $id and $descriptions. So far I know I need
open(IN,'file.txt'); while($line = <IN>) { chomp $line; ($id, $description)### regex expression to split it push(%hash{$id, $descriptions)### then a push? }
I hope you can help guys, I'm new at programming, so far I'm doing ok, but this has stumped me. Thanks in advance

Replies are listed 'Best First'.
Re: Hash from a file
by ikegami (Patriarch) on Oct 04, 2007 at 15:23 UTC
    use strict; use warnings; my $file = 'file.txt'; open(my $fh, '<', $file) or die("Unable to open input file \"$file\": $!\n"); my %hash; while (<$fh>) { chomp; my ($dtype, $rest) = split(/:/, $_, 2); my ($id, $desc) = split(/\t/, $rest, 2); $hash{$id} = $desc; }

    or

    while (<$fh>) { my ($id, $desc) = /^[^:]*:([^\t]*)\t(.*)$/; $hash{$id} = $desc; }

    Update: Fixed the bug naikonta identified.

      $ perl 642676.pl Can't use global $_ in "my" at 642676.pl line 10, near ", $_" Global symbol "%hash" requires explicit package name at 642676.pl line + 12. Execution of 642676.pl aborted due to compilation errors.

      Reassignment of $_ might be tricky but I don't see any point other than shorter variable name.


      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: Hash from a file
by toolic (Bishop) on Oct 04, 2007 at 15:32 UTC
    Is this what you had in mind?
    use warnings; use strict; use Data::Dumper; my %hash; while (<DATA>) { my ($id, @description) = split; $hash{$id} = [@description]; } # let's print out what we have print Dumper( \%hash ); __DATA__ Data_Type:1234567890 data data data data data Data_Type:1237834810 data2 data2 data2 data2 data2

    This prints out:

    $VAR1 = { 'Data_Type:1234567890' => [ 'data', 'data', 'data', 'data', 'data' ], 'Data_Type:1237834810' => [ 'data2', 'data2', 'data2', 'data2', 'data2' ] };
      Kind of...what I want is it to be split like...
      'Data_Type:1237834810' => ['data2 data2 data2 data2 data2']
      Can't say how grateful I am for this btw!
        Be careful. Saying ['data2 data2 data2 data2 data2'] means that the value is an array reference with a single element, 'data2 data2 data2 data2 data2', which is a string. It's not the same as ['data2', 'data2', 'data2', 'data2', 'data2'] which is an array reference consist of some elements that are all strings. If what you want is the latter, then toolic has given the answer.

        However, if what you want is the former then you can join back @description separated by, for example, spaces. This also replaces tabs with single spaces. From toolic's code:

        my ($id, @description) = split; $hash{$id} = [join ' ', @description];

        Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: Hash from a file
by mwah (Hermit) on Oct 04, 2007 at 16:06 UTC
    AnonymousI've got a file that I need to read
    into a hash line by line


    Just map key/value directly into the hash:
    ... my %hash; open my $fh,'<', 'input.txt' or die "with style ($!)"; %hash = map /^Data_Type:([\S]+)\s*([^\n]+)/, <$fh>; # all happens her +e close $fh; ...
    You can verify with:
    ... print "$_ = > $hash{$_}\n" for keys %hash; ...
    Regards

    mwa