I came across CPAN Deep::Hash::Utils giving the approach below which seems simple enough. I also looked at the modules suggested by Re: A more elegant way to filter a nested hash? ( data xpath, dpath, diver, walk, walker, visitor, jquery, pquery, json path, css csel, MarpaX::xPathLike) and like the suggestions on existing art.
use Deep::Hash::Utils qw(reach nest deepvalue);
sub hash_filter {
my ($source, $filter) = @_;
my %rc;
while (my @l = reach($filter)) {
pop @l;
if (defined( my $source_val = deepvalue($source, @l) ) ) {
# hint: work around nest behavior on even vs odd key count
nest(\%rc, @l)->{ $l[$#l] } = $source_val;
}
}
\%rc;
}