For posterity,
Here's another approach that avoids loading the entire list in memory and also neglects the use of -M (it relies specifically on the naming convention of the candidate target files in OP's description).
hauxex points out some caveats using the -M file tests that could render its use unreliable. Gabor Szabo also highlights its weirdness.
Sharing the code below to illustrate the idea behind the computation of the psuedo_mtime field which was used for comparisons.
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long qw ( :config no_ignore_case bundling );
use Pod::Usage qw ( pod2usage );
# parse options
my (%opt,$dir);
GetOptions(\%opt, "help|h", "verbose|v", "test|t", "version", "directo
+ry|d=s" => \$dir) ||
pod2usage(-verbose => 0);
pod2usage(-verbose => 1, -exitval => 1) if $opt{'help'};
pod2usage(-verbose => 99, -exitval => 0, -sections => [qw(VERSION)]) i
+f $opt{'version'};
pod2usage(-verbose => 0, -message => "$0: No directory given\n") if !
+$dir;
my @AGE_RATIONALISER = (31104000,2592000,86400,3600,60,1); # yy,mm,dd,
+hh,mm,ss converted to secs
my $processed_hash_ref;
opendir DH, $dir or die "Couldn't open directory $dir: $!";
chdir $dir; # filetests using relative path
while ($_ = readdir (DH)) {
next unless -f $_
&& m/^\d_\d{4}_\d\d?_\d\d?_\d\d?_\d\d?_\d\d?_table/i;
my @old_fname = split /_/;
my $new_fname = join ('_', @old_fname[ 7..11 ]);
my $psuedo_mtime = 0; # divine a fake but consistent mtime f
+rom the filename
$psuedo_mtime += $old_fname[$_+1] * $AGE_RATIONALISER[$_] for (0..
+$#AGE_RATIONALISER);
# already seen a more recent file with the name we're
# planning to use? skip current file
next if defined $processed_hash_ref->{$new_fname} &&
$processed_hash_ref->{$new_fname}->{AGE} > $psuedo_mtime;
# file safe to be renamed... for now
$processed_hash_ref->{$new_fname}->{OLDNAME} = $_;
$processed_hash_ref->{$new_fname}->{AGE} = $psuedo_mtime;
}
closedir DH;
# now proceed to rename items
map {
print "[!] rename $processed_hash_ref->{$_}->{OLDNAME} to $_\n" if
+ $opt{'verbose'};
rename $processed_hash_ref->{$_}->{OLDNAME}, $_ unless $opt{'test'
+};
} keys %$processed_hash_ref;
__END__
=head1 NAME
=over 4
rename.pl - file renaming utility
=back
=head1 SYNOPSIS
=over 4
rename.pl [-t | --test] {-d log-file-directory}
rename.pl [-v | --verbose] {-d log-file-directory}
rename.pl [-h | --help]
rename.pl [--version]
=back
=head1 OPTIONS
=over 4
=item B<-t, --test>
Test run - no renaming takes place - effectively a simulation
=item B<-v, --verbose>
Verbose - printout of files to be renamed
=item B<-h, --help>
Help - prints this manual
=back
=head1 DESCRIPTION
B<This program> will read the given directory and rename a
contingent of the files within said directory. Files to be
renamed that share the same target name - will have only
the most recent one renamed.
=head1 AUTHORS
Shadowsong
=head1 VERSION
0.0.1-beta
=cut