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

Hi Monks! I'm trying to read data from a file and insert the data into a complex data structure. I have a file like this:
Paragraph1
key=value
Paragraph2
key=value
key=value
Paragraph3
.. and so forth..
I really can't find a way to do it,i want some multidimensional structure so that given paragraph5 i can access all the keys and change the values or add a line or delete it. I tried using array of array of hashes and other mix but no luck. Thank you for your help

Replies are listed 'Best First'.
Re: insert data into data structure
by choroba (Cardinal) on Nov 30, 2015 at 09:46 UTC
    Hi Genmai, welcome to the Monastery!

    Can you show us what you tried? We can probably find the errors in your code, which would help you learn much more than just using someone else's code.

    Hash of hashes seems sufficient for what you've described:

    Paragraph1 => { key1 => 'value1', key2 => 'value2', }, ...
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      I really would like to show you some code but there is no good code to show and the one i had i just deleted it. This is more or less the code i had before falling asleep in the chair yesterday:
      for my $line (@data)
      {
          if($line =~ /^\.+\$/)
          {
              $nameTmp = $line;
              push @listSection, $nameTmp, \@arrTmp;
          }
          elsif($line =~ /(.+)=(.+)|#(.*)/)
          {
              %hashTmp =
              (
              key => "$1",
              value => "$2",
              comment => "$3",
              );
              push @arrTmp, \%hashTmp;
          }
      }
      print "\n";
      print Dumper(@listSection);
        This if($line =~ /^\.+\$/) probably doesn't do what you want. To my eyes, it only matches a line that begins .+$, but backslash $ doesn't seem to do anything other than mess up the match. You might try the Regular Expression test page. If that first line doesn't match, you never get anything in @listSection, so there's nothing to Dump.

        Sometimes I can think of 6 impossible LDAP attributes before breakfast.

        http://act.yapc.eu/lpw2015/ It's that time of year again!

Re: insert data into data structure
by AnomalousMonk (Archbishop) on Nov 30, 2015 at 17:28 UTC
Re: insert data into data structure
by kcott (Archbishop) on Dec 01, 2015 at 04:59 UTC

    G'day Genmai,

    Welcome to the Monastery.

    Your test data is poor:

    • There's no way to differentiate between all the identical keys.
    • There's no way to differentiate between all the identical values.
    • I question whether it is representative of your real data.

    I also note that, after you previewed posts and saw that they didn't match your real code, you went ahead and posted them anyway. You'll find that monks are not particularly inclined to spend much time responding when the poster can't be bothered to make much effort. Please aim to do better in future: we don't like looking at crap and you're the one who suffers.

    Here's the guts of what you (probably) need:

    #!/usr/bin/env perl use strict; use warnings; use Data::Dump; my (%data, $topkey); while (<DATA>) { chomp; $data{$topkey}{$1} = $2 and next if /^(.*?)=(.*?)$/; $topkey = $_; } dd \%data; __DATA__ Paragraph1 key1=valueA Paragraph2 key2=valueB key3=valueC Paragraph3

    Output:

    { Paragraph1 => { key1 => "valueA" }, Paragraph2 => { key2 => "valueB", key3 => "valueC" }, }

    Update: Fixed typo: s/can be bothered/can't be bothered/. Many thanks, hippo, for catching this.

    — Ken