Using perl:
$ perl -MFile::Basename -e '
my @files = glob q(*.rar);
my %bases;
foreach (@files) {
my ($b, $p) = split /\.part/, basename $_, q(.rar);
$bases{$b} = $p if (!defined $bases{$b} or $p > $bases{$b});
};
foreach my $k (sort keys %bases) {
print "$k.part$bases{$k}.rar\n"
}'
1yBWVnZCx8CoPrGIG.part23.rar
DaHs0QJnJbt.part4.rar
RSmWMPb0vWr8LIEFtR7o.part5.rar
T7yvBIqHK82qDCNTtz9iuvp2NhQ.part11.rar
W1Pn8SHf7pbMSf1u99C4f.part2.rar
XYcUpv7b1ZpcczFT5y7Uc9mQTvAf88kl.part2.rar
n5oTzoLvG.part6.rar
okgbuh8VUxSguDNra9uMTtDlXhiLWQmY.part2.rar
tBJDjsyJtFpY0d3aQ.part6.rar
This firstFirst this gets all the filenames matching the glob *.rar into an array called @files. Then it uses map to convertconverts the array into a hash (aka associative array) called %bases where each key is the base filename and the value is the highest part number seen for that basename.
Then it prints out each basename with the part number in the same format as the original filenames: base.partN.rar
This uses the File::Basename module, which is included with perl as part of its standard library.
There are shorter, more obfuscated ways to do this in perl, but this IMO is a nice balance between brevity and readability. It was written to pass the restrictions of use strict (or -Mstrict on the command-line), so it could be re-used as part of a larger script. That's why there are all the my declarations that are usually skipped for one-liners.