Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

hash magic

by hrmnbth (Initiate)
on Mar 14, 2013 at 13:13 UTC ( #1023471=perlquestion: print w/ replies, xml ) Need Help??
hrmnbth has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks
I need some hash magic if you can please help me.

I have the following text input and I want to build a multilevel hash from it

INPUT

Host_001 -> objectID -> HOST.62 Host_001 -> name -> rapidqa Host_001_WWN_001 -> WWN -> 21.00.00.E0.8B.80.7E.7D Host_001_WWN_002 -> WWN -> 21.00.00.E0.8B.80.E7.7F Host_001_LogicalUnit_001 -> objectID -> LU.R700.87108.8234 Host_001_LogicalUnit_001 -> devNum -> 8234 Host_001_LogicalUnit_002 -> objectID -> LU.R700.87108.8235 Host_001_LogicalUnit_002 -> devNum -> 8235 Host_002 -> objectID -> HOST.107 Host_002 -> name -> sapfvir03 Host_002_WWN_001 -> WWN -> 21.00.00.E0.8B.81.D7.F6 Host_002_WWN_002 -> WWN -> 21.00.00.E0.8B.81.4C.F9 Host_002_LogicalUnit_001 -> objectID -> LU.R700.87108.10336 Host_002_LogicalUnit_001 -> devNum -> 10336

What i want to do is loop through the text and dynamically create a hash, the problem is the how to dynamically add to a hash, below is an example of what i'll need in code format not in syntax

$hash{Host}{001}{objectID} = HOST.62; $hash{Host}{001}{name} = rapidqa; $hash{Host}{001}{WWN}{001}{WWN} = 21.00.00.E0.8B.80.7E.7D; $hash{Host}{001}{WWN}{002}{WWN} = 21.00.00.E0.8B.80.E7.7F; $hash{Host}{001}{LogicalUnit}{001}{objectID} = LU.R700.87108.8234; $hash{Host}{001}{LogicalUnit}{001}{devNum} = 8234; $hash{Host}{001}{LogicalUnit}{002}{objectID} = LU.R700.87108.8235; $hash{Host}{001}{LogicalUnit}{002}{devNum} = 8235; $hash{Host}{002}{objectID} = HOST.107; $hash{Host}{002}{name} = sapfvir03; $hash{Host}{002}{WWN}{001}{WWN} = 21.00.00.E0.8B.81.D7.F6; $hash{Host}{002}{WWN}{002}{WWN} = 21.00.00.E0.8B.81.4C.F9; $hash{Host}{002}{LogicalUnit}{001}{objectID} = LU.R700.87108.10336; $hash{Host}{002}{LogicalUnit}{001}{devNum} = 10336;

Thank you

Comment on hash magic
Select or Download Code
Re: hash magic (hash from path)
by Anonymous Monk on Mar 14, 2013 at 13:16 UTC
      #!/usr/bin/perl -- use strict; use warnings; use Data::Dump; use Data::Diver qw/ DiveVal /; open my $fh, '<', \q{Ho|001 -> ooB -> Ho.62 Ho|001 -> nom -> rapidqa Ho|001|VAG|001 -> VAG -> 21.00.00.E0.8B.80.7E.7D Ho|001|VAG|002 -> VAG -> 21.00.00.E0.8B.80.E7.7F Ho|001|BigUnit|001 -> ooB -> LU.R700.87108.8234 Ho|001|BigUnit|001 -> deR -> 8234 Ho|001|BigUnit|002 -> ooB -> LU.R700.87108.8235 Ho|001|BigUnit|002 -> deR -> 8235 Ho|002 -> ooB -> Ho.107 Ho|002 -> nom -> sapfvir03 Ho|002|VAG|001 -> VAG -> 21.00.00.E0.8B.81.D7.F6 Ho|002|VAG|002 -> VAG -> 21.00.00.E0.8B.81.4C.F9 Ho|002|BigUnit|001 -> ooB -> LU.R700.87108.10336 Ho|002|BigUnit|001 -> deR -> 10336 }; my $root = {}; while(<$fh>){ s/\s+$//; my( $left, $mid, $right ) = split ' -> ', $_; my @paths = map { \$_ } split(/\|/, $left), $mid; DiveVal( $root, @paths ) = $right; } dd $root; __END__ { Ho => { "001" => { BigUnit => { "001" => { deR => 8234, ooB => "LU.R700.87108.8 +234" }, "002" => { deR => 8235, ooB => "LU.R700.87108.8 +235" }, }, nom => "rapidqa", ooB => "Ho.62", VAG => { "001" => { VAG => "21.00.00.E0.8B.80.7E.7D" }, "002" => { VAG => "21.00.00.E0.8B.80.E7.7F" }, }, }, "002" => { BigUnit => { "001" => { deR => 10336, ooB => "LU. +R700.87108.10336" } }, nom => "sapfvir03", ooB => "Ho.107", VAG => { "001" => { VAG => "21.00.00.E0.8B.81.D7.F6" }, "002" => { VAG => "21.00.00.E0.8B.81.4C.F9" }, }, }, }, }
Re: hash magic
by sundialsvc4 (Abbot) on Mar 14, 2013 at 13:30 UTC

    Perl to the rescue!   Read up on the topic of auto-vivification, which is a fancy-pants way of saying that something “just springs to life automatically.”   Hash structures of fairly arbitrary complexity can be fairly instantly built that way.

    For example, consider:
    $foo->{"1"}->{"a"}->{3}->{"foobar"}++;

    Without you doing anything out-of-the-way at all, $foo will become a hashref and, just like that, it will have a key 1 which contains a hashref with a key a ... and so on ... and at the tail of the thing will be the number 1, filed under foobar, because that key sprang into existence with the value zero (which is what it needs to be because it’s about to be incremented), which got incremented by the ++ operator.   If you execute the statement again, well, the entire data structure already exists, and now the value at the tail of it is 2.

    If that ain’t magic, I don’t know what is.   You will just need to craft a regular-expression to pull the string apart, then you can just write the one statement to create the entire data structure, and it will “just work.™”

      Perl to the rescue! ...

      That is not Perl, that is English

Re: hash magic
by BrowserUk (Pope) on Mar 14, 2013 at 13:35 UTC

    #! perl -slw use strict; use Data::Dump qw[ pp ]; my %hash; while( <DATA> ) { chomp; my $r = \%hash; my @bits = split '\s+->\s+|_', $_; $r = $r->{ shift( @bits ) } //= {} while @bits > 2; $r->{ $bits[ 0 ] } = $bits[ 1 ]; } pp \%hash; __DATA__ Host_001 -> objectID -> HOST.62 Host_001 -> name -> rapidqa Host_001_WWN_001 -> WWN -> 21.00.00.E0.8B.80.7E.7D Host_001_WWN_002 -> WWN -> 21.00.00.E0.8B.80.E7.7F Host_001_LogicalUnit_001 -> objectID -> LU.R700.87108.8234 Host_001_LogicalUnit_001 -> devNum -> 8234 Host_001_LogicalUnit_002 -> objectID -> LU.R700.87108.8235 Host_001_LogicalUnit_002 -> devNum -> 8235 Host_002 -> objectID -> HOST.107 Host_002 -> name -> sapfvir03 Host_002_WWN_001 -> WWN -> 21.00.00.E0.8B.81.D7.F6 Host_002_WWN_002 -> WWN -> 21.00.00.E0.8B.81.4C.F9 Host_002_LogicalUnit_001 -> objectID -> LU.R700.87108.10336 Host_002_LogicalUnit_001 -> devNum -> 10336

    Outputs:

    C:\test>junk92 { Host => { "001" => { LogicalUnit => { "001" => { devNum => 8234, objectID => "LU.R7 +00.87108.8234" }, "002" => { devNum => 8235, objectID => "LU.R7 +00.87108.8235" }, }, WWN => { "001" => { WWN => "21.00.00.E0.8B.80.7E.7D" } +, "002" => { WWN => "21.00.00.E0.8B.80.E7.7F" } +, }, name => "rapidqa", objectID => "HOST.62", }, "002" => { LogicalUnit => { "001" => { devNum => 10336, object +ID => "LU.R700.87108.10336" } }, WWN => { "001" => { WWN => "21.00.00.E0.8B.81.D7.F6" } +, "002" => { WWN => "21.00.00.E0.8B.81.4C.F9" } +, }, name => "sapfvir03", objectID => "HOST.107", }, }, }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Thank you all, you are beeeeatiful

Re: hash magic
by hdb (Prior) on Mar 15, 2013 at 10:36 UTC
    I love regexps, so I create Perl code from your data and eval it. Just make sure no-one can add Perl code to your data...
    use strict; use Data::Dump qw[ pp ]; my %hash; while(<DATA>) { chop; s/\s*(_|->)\s*/\"\}\{\"/g; # "_" or "->" creates a new level in th +e hash s/(.*)\{/\1=/; # replace rightmost { with = eval( '$hash{"'.$_.'";' ); # put into hash } pp \%hash; __DATA__ Host_001 -> objectID -> HOST.62 Host_001 -> name -> rapidqa Host_001_WWN_001 -> WWN -> 21.00.00.E0.8B.80.7E.7D Host_001_WWN_002 -> WWN -> 21.00.00.E0.8B.80.E7.7F Host_001_LogicalUnit_001 -> objectID -> LU.R700.87108.8234 Host_001_LogicalUnit_001 -> devNum -> 8234 Host_001_LogicalUnit_002 -> objectID -> LU.R700.87108.8235 Host_001_LogicalUnit_002 -> devNum -> 8235 Host_002 -> objectID -> HOST.107 Host_002 -> name -> sapfvir03 Host_002_WWN_001 -> WWN -> 21.00.00.E0.8B.81.D7.F6 Host_002_WWN_002 -> WWN -> 21.00.00.E0.8B.81.4C.F9 Host_002_LogicalUnit_001 -> objectID -> LU.R700.87108.10336 Host_002_LogicalUnit_001 -> devNum -> 10336

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1023471]
Approved by marto
Front-paged by vinoth.ree
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-11-20 21:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (101 votes), past polls