use File::Find; finddepth sub { my $old = $_; return unless -f and s/\.abc$/.def/; warn("won't overwrite existing file at $File::Find::name"), return if -e; rename $old, $_ or warn "Cannot rename $old to $_ in $File::Find::dir: $!"; }, ".";