Hi Perl monks I was hoping you might be able to advise me on how best to do the following. I have been trying for ages but I just cant seem to get it working. I have a large complex data structure that is a hash of hashes of hashes. I am able to parse this but I am struggling with matching up some of key values. Below is a small sample of the data structure at this level that I am trying to parse. As you will see in some of the hashes %filer_device is hash, some of them %filer_volume is a hash, some of them neither is a hash and some of them both are hashes.
"bigstorderv_mpt" => { "%export_name" => "/bb/bigstor/derv", "%filer_device" => "nydevnfs_derv", "%filer_volume" => "/vol/derv" }, "bigstormtg_mpt" => { "%export_name" => "/bb/bigstor/mtgmodel", "%filer_device" => { "\@ridge" => "njdevnfs_mtge", "\@west" => "nydevnfs_mtge" }, "%filer_volume" => "/vol/mtge" }, "build10_mpt" => { "%export_name" => "/bb/source", "%filer_device" => { "\@ridge" => "rnap7751-s", "\@west" => "nydevnfs_sunbbsource" }, "%filer_volume" => { "\@ridge" => "/vol/sunbbsource_c", "\@west" => "/vol/sunbbsource" } },
I have written this subroutine to try and deal with these nested hashes
while (my( $kTag, $vTag ) = each %{$nfshashofhashes} ) { next if ( ref $vTag ne 'HASH' ); print "TAG > $kTag\n"; my $default = delete $vTag->{'%default'}; while (my( $kNFSMNT, $vNFSMNT ) = each %{$vTag} ) { next if ($kNFSMNT =~ m/optswt_nfs\b/); #print "...$kTag $kNFSMNT\n"; my $default = delete $vNFSMNT->{'default'} // delete $ +vNFSMNT->{'%default'}; while (my($kDEFAULT, $vDEFAULT) = each %{$default}) { + #Get all the defaults key/value pairs for each nfs hash #print "$kNFSMNT:$kDEFAULT $vDEFAULT\n"; $MNTOPTS = "$vDEFAULT" if ($kDEFAULT eq '%mount_op +ts'); $MNTUSER = "$vDEFAULT" if ($kDEFAULT eq '%mount_us +er'); $MNTGRP = "$vDEFAULT" if ($kDEFAULT eq '%mount_gro +up'); $MNTACL = "$vDEFAULT" if ($kDEFAULT eq '%mount_acl +'); } while (my( $kNFSTOKEN, $vNFSTOKEN ) = each %{$vNFSMNT} + ) { next if ( $kNFSTOKEN =~ m/\%comment\b/ ); #print "*** $kTag $kNFSTOKEN $vNFSTOKEN\n"; #Prin +ts @dev home7_mpt, @dev home-lnk-mpt etc and value which is a hash co +ntaing %export_name, %filer_device etc $FILERDEVICE = $vNFSTOKEN->{'%filer_device'}; $FILERDEVICEHASH = ref $FILERDEVICE ? $FILERDEVICE + : { '' => $FILERDEVICE }; $FILERVOLUME = $vNFSTOKEN->{'%filer_volume'}; $FILERVOLUMEHASH = ref $FILERVOLUME ? $FILERVOLUME + : { '' => $FILERVOLUME }; $EXPORTFS = $vNFSTOKEN->{'%export_name'}; #print "$kTag $kNFSTOKEN $FILERDEVICE $FILERVOLUME + $EXPORTFS\n"; ###Process %filer_device and %filer_volume. Someti +mes %filer_device is a hash. Sometimes %filer_volume is a hash. Somet +imes both are hashes. Sometimes neither are hashes :-( # my ($FDEVICE, $WESTFDEVICE, $RIDGEFDEVICE, $VOLUME +, $WESTVOL, $RIDGEVOL); for my $DataCenterFD (keys %{$FILERDEVICEHASH}) { $FDEVICE = $FILERDEVICEHASH->{$DataCenterFD} / +/ $FILERDEVICEHASH->{''}; #print "$DataCenterFD\n"; for my $DataCenterVD (keys %{$FILERVOLUMEHASH} +) { $VOLUME = $FILERVOLUMEHASH->{$DataCenterVD +} // $FILERVOLUMEHASH->{''}; #print "$DataCenterVD\n"; ##NEARLY WORKING. JUST NEED TO MATCH VOLUM +E VALUES TO EITHER A @WEST/@RIDGE FILERDEVICE @WEST/@RIDGE #This prints out a line in this format: @d +ev bigstormtg_mpt @ridge /bb/bigstor/mtgmodel /vol/mtge print "$kTag $kNFSTOKEN $FDEVICE $DataCent +erFD $EXPORTFS $VOLUME\n"; } } } } } }
The problem I am having is that the filer_device value doesn't match up with what the filer_volume is defined as. So for instance if there is a hash %filer_device with keys @west and @ridge then the filer_device key @west needs to be mapped to the filer_volume @west key value and the same for the @ridge values if these are defined.
In reply to How to check that keys in two hashes match and get the corresponding values by NewLondonPerl1
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |