I'd suggest rethinking your data structure a bit. The reason you're having a hard time with it is that the data structure isn't regular, so your code is obfuscated by all sorts of special case handling. I couldn't tell what you're wanting to do by looking at your code.
Looking at the data, your code and the desired output gave me enough to go on, though. At first, I tried to clean up your code to get it going, but it was just too different from how I would've done it, that I kept getting confused. So I just started from scratch and came up with this:
$ cat 1028644.pl #!/usr/bin/perl use strict; use warnings; my $nfshashofhashes = { "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" } }, "build11_mpt" => { "%export_name" => "/bb/source", "%filer_device" => { "fridge" => "rnap7751-s", "\@west" => "nydevnfs_sunbbsource", }, "%filer_volume" => { "\@ridge" => "/vol/sunbbsource_c", "\@west" => "/vol/sunbbsource", "qwest" => "/vol/sunquirks", } }, }; while ( my ($MPT, $rMPT) = each %{$nfshashofhashes} ) { die "MPT<$MPT> NOT A HASH!\n" unless ref $rMPT eq 'HASH'; die "MPT<$MPT> WRONG STRUCTURE!\n" unless exists $rMPT->{'%export_ +name'}; my $EXP = $rMPT->{'%export_name'}; # Set default value and hash ref for devices my ($rFILDEV, $DEVDFLT, $t); $t = $rMPT->{'%filer_device'}; if (ref $t eq 'HASH') { $rFILDEV = $t; $DEVDFLT = '????'; } else { $rFILDEV = { }; $DEVDFLT = $t; } # Same for volumes my ($rFILVOL, $VOLDFLT); $t = $rMPT->{'%filer_volume'}; if (ref $t eq 'HASH') { $rFILVOL = $t; $VOLDFLT = '????'; } else { $rFILVOL = { }; $VOLDFLT = $t; } # Match up the VOL and DEV entries in the hash. Missing values fo +r # DEV and VOL will be filled in with the DFLT values as needed. my %MATCHUP; $MATCHUP{$_}{VOL} = $rFILVOL->{$_} for keys %$rFILVOL; $MATCHUP{$_}{DEV} = $rFILDEV->{$_} for keys %$rFILDEV; # If both were scalars, MATCHUP is empty, so make a single matchin +g record $MATCHUP{'BAR'} = { DEV=>$DEVDFLT, VOL=>$VOLDFLT } if ! keys %MATC +HUP; # And our final results... for (keys %MATCHUP) { my $DEV = $MATCHUP{$_}{DEV} // $DEVDFLT; my $VOL = $MATCHUP{$_}{VOL} // $VOLDFLT; printf "%-20.20s %-20.20s %-20.20s %-20.20s\n", $MPT, $DEV, $VOL, $EXP; } } $ perl 1028644.pl bigstorderv_mpt nydevnfs_derv /vol/derv /bb/big +stor/derv build11_mpt ???? /vol/sunbbsource_c /bb/sou +rce build11_mpt rnap7751-s ???? /bb/sou +rce build11_mpt ???? /vol/sunquirks /bb/sou +rce build11_mpt nydevnfs_sunbbsource /vol/sunbbsource /bb/sou +rce build10_mpt rnap7751-s /vol/sunbbsource_c /bb/sou +rce build10_mpt nydevnfs_sunbbsource /vol/sunbbsource /bb/sou +rce bigstormtg_mpt njdevnfs_mtge /vol/mtge /bb/big +stor/mtgmodel bigstormtg_mpt nydevnfs_mtge /vol/mtge /bb/big +stor/mtgmodel
I think that'll do it for you. You didn't specify what you were expecting when you had two hashes with mismatched keys, so I added "build11_mpt" to demonstrate it. Feel free to change it as you need it.
Since I had trouble wrapping my head around your code, I fully expect you might have a little difficulty with mine, so feel free to ask questions.
...roboticus
When your only tool is a hammer, all problems look like your thumb.
In reply to Re: How to check that keys in two hashes match and get the corresponding values
by roboticus
in thread How to check that keys in two hashes match and get the corresponding values
by NewLondonPerl1
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |