You could use the -d test to look for entries that are themselves directories and then recurse down into them but at that point you'd have started down the path of reimplementing what something like Path::Tiny (or File::Find, or File::Find::Rule, or Path::Iterator::Rule, or . . .) could do for you off the shelf so you'd be better of using that to begin with.
## presuming your sample vars for dir, old, new
## Somewhat untested, but . . .
use Path::Tiny qw( path );
my $iter = path( $dir )->iterator( { recurse => 1 } );
while( my $path = $iter->() ) {
next unless $path->is_file and $path =~ m{\. $old $}x;
my $new_path = $path->basename( $old ) . ".$new";
unless( my $ret = $path->move( $new_path ) ) {
warn "Problem moving '$path': $ret\n";
}
}
The cake is a lie.
The cake is a lie.
The cake is a lie.