Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Parsing text file into a hash with multiple values per key

by Kenosis (Priest)
on Oct 03, 2012 at 22:41 UTC ( #997143=note: print w/ replies, xml ) Need Help??


in reply to Parsing text file into a hash with multiple values per key

If I've understood your issue, consider the following:

use strict; use warnings; my ( $host, %hash ); while (<DATA>) { chomp; next if /Folder/ or not $_; my ( $type, $name ) = /(\S+)\s*:\s*(\S+)/; if ( $type =~ "Host" ) { $host = $name; } elsif ( $type =~ "VM" ) { my $guest = $name; push @{ $hash{$host} }, $guest unless $guest ~~ @{ $hash{$host +} }; } } print "Key '$_' has " . (scalar @{ $hash{$_} }) . " values.\n" for key +s %hash; __DATA__ *******************Folder North*************** Folder : North Folder : Lab Host : host42016 VM : host42229 VM : host42235 VM : host42236 VM : host42237 VM : host42238 VM : host42239 VM : host42240 VM : host42241 VM : host42242 VM : host42252 Host : host42049 VM : host42361 VM : host42362 VM : host42363 VM : host42364 VM : host42365 VM : host42366 VM : host42367 VM : host42368 VM : host42369 VM : host42370 *******************Folder South*************** Folder : South Folder : Staging Host : host42124 VM : host42248 VM : host42249 VM : host42250 VM : host42230 VM : host42251 VM : host42243 VM : host42244 VM : host42245 VM : host42246 VM : host42247 Host : host42125 VM : host42299 VM : host42300 VM : host42301 VM : host42302 VM : host42303 VM : host42304 VM : host42305 VM : host42306 VM : host42307 VM : host42308

Output:

Key 'host42049' has 10 values. Key 'host42125' has 10 values. Key 'host42016' has 10 values. Key 'host42124' has 10 values.

Only a few modifications have been made to your code.

Am not sure I understand removing duplicate hosts. If hosts are hash keys, there will be no duplicates. Duplicate VM's are avoided by first checking--via Perl's smart matching (v5.10+)--if the VM is already in the array, and the captured VM is pushed onto the array only if it's not already there.

Hope this helps!

Update: Anonymous Monk's suggestion of using a hash of hashes (HoH) is an excellent one, as it would be faster, and would work on older Perl versions which don't support smart matching. Here's a HoH version that would operate on the same data set as above, and would generate the same output:

use strict; use warnings; my ( $host, %hash ); while (<DATA>) { chomp; next if /Folder/ or not $_; my ( $type, $name ) = /(\S+)\s*:\s*(\S+)/; if ( $type =~ "Host" ) { $host = $name; } elsif ( $type =~ "VM" ) { my $guest = $name; $hash{$host}{$guest}++; } } print "Key '$_' has " . ( values %{ $hash{$_} } ) . " values.\n" for k +eys %hash;


Comment on Re: Parsing text file into a hash with multiple values per key
Select or Download Code
Re^2: Parsing text file into a hash with multiple values per key
by Anonymous Monk on Oct 03, 2012 at 22:43 UTC
    FWIW, checking for duplicates once after exit the loop should suffice :)

      Yes--good point.

Re^2: Parsing text file into a hash with multiple values per key
by dayton (Novice) on Oct 03, 2012 at 22:53 UTC
    Ah... thanks, that did it...don't know why I couldn't see that.

    $guest unless $guest takes care of the duplicates I was seeing.

    I'd tried (scalar @{ $hash{$_} }) but must have munged some of the syntax. Thanks again, problem solved.

      You're most welcome! Am glad these worked for you.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://997143]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2015-07-04 09:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (59 votes), past polls