If I'm understanding you correctly (i.e. that key names should be changed to the value indicated by 'replval' => ... in the respective %c_hash entry, if such an entry exists), you want something like this:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my %xhash = ('a' => {
'b' => {
'e' => 'E',
'c' => 'C',
'content' => 'B
'
},
'content' => 'A
',
'd' => 'D'
});
my %c_hash=('a' => {
'addval' => {
'b' => {
'addval' => {
'e' => {
'addv
+al' => {},
'repv
+al' => '5'
},
'c' => {
'addv
+al' => {},
'repv
+al' => '3'
}
},
'repval' => '2'
},
'd' => {
'addval' => {},
'repval' => '4'
}
},
'repval' => '1'
});
sub traverse {
my ($hash, $callback, $mode) = @_;
return unless ref($hash) eq "HASH";
for my $key (keys %$hash) {
my $val = $hash->{$key};
if (ref($val) eq "HASH") {
traverse($val, $callback, $mode);
if ($mode eq "collect") {
if (exists $val->{repval}) {
$callback->($key, $val->{repval});
}
}
}
if ($mode eq "replace") {
$callback->($key, $val, $hash);
}
}
}
my %repl; # lookup table: a => 1, etc.
traverse(\%c_hash,
sub {
my ($key, $val) = @_;
$repl{$key} = $val;
},
"collect"
);
# print Dumper \%repl; # debug
traverse(\%xhash,
sub {
my ($key, $val, $href) = @_;
if (exists $repl{$key}) {
my $newkey = $repl{$key};
$href->{$newkey} = $val;
delete $href->{$key};
}
},
"replace"
);
print Dumper \%xhash;
__END__
$VAR1 = {
'1' => {
'4' => 'D',
'content' => 'A
',
'2' => {
'3' => 'C',
'content' => 'B
',
'5' => 'E'
}
}
};
Note that as you can't rename hash keys, you have to create new key-value pairs (new key, old value), while deleting the old entries.