It might be easier to process the directory tree in two passes. I'm thinking something like the following might work:
#!/usr/bin/perl
use warnings;
use strict;
use File::Find;
my %targetdir;
my %visiteddir;
sub wanted_stage1 {
return unless -f;
$targetdir{$File::Find::dir}++ if /\.old$/;
}
sub postprocess {
return unless $targetdir{$File::Find::dir};
return if $visiteddir{$File::Find::dir}++;
print "Changing files in $File::Find::dir\n";
}
# build list of directories containing *.old files:
find({wanted => \&wanted_stage1}, ".");
print "Directories to process: @{[sort keys %targetdir]}\n";
# process files in directory list:
find({wanted => sub{}, postprocess => \&postprocess}, sort keys %targe
+tdir);
__END__
.:
code.pl
code.txt
one
two
./one:
bar
foo
three
./one/three:
four
something.old
./one/three/four:
blah
something.old
./two:
bar
foo
something.old
Directories to process: ./one/three ./one/three/four ./two
Changing files in ./one/three/four
Changing files in ./one/three
Changing files in ./two