in reply to Sorting filenames with custom function

Custom sorting is a FAQ: How do I sort an array by (anything)?. In your case, splitting on the last underscore (split /_(?!.*_)/, $var;) combined with the string comparison operator cmp should be helpful in your comparison.

Replies are listed 'Best First'.
Re^2: Sorting filenames with custom function
by AnomalousMonk (Archbishop) on May 13, 2010 at 22:10 UTC
    ... I would like to sort these filenames based on the number after the last underscore ...

    This implies the OPer wants a numeric comparison of an extracted set of digits, so the  <=> (also in Equality Operators; see perlop) numeric comparator would be appropriate here.

      But the numbers presented are zero-padded integers, so the comparison is equivalent. If the numeric comparator were used with the simple split, a non-numeric comparison warning will be thrown (he does have warnings on, right?). Not all files listed have the .jpg file extension, so (split /_|\./, $a)[-2] won't work. I was also trying to keep it short/simple, preventing a long code block and making it easier for the OP to build his own. The best I came up with for using the numeric comparator sorted based upon the last block of digits:

      my $re = qr/\d+/; print join "\n", sort {($a =~ /$re/g)[-1] <=> ($b =~ /$re/g)[-1]; } @n +ames

      But then I'd have to link to perlretut and Regexp Quote Like Operators as well...

        ... the numbers presented are zero-padded integers [with three digits each], so the comparison is equivalent.

        Aye, there's the rub. The OPer only presents three examples and, in general, about 35% of the info needed to build some robust code. Numeric and string comparison are the same until someone sez "Oh, by the way..."

        It's just a guess, but I'd be inclined to fortify myself on the numeric side based on the presence of the word "number" in the OP: confronted with real-world data (whatever that may be), a numeric comparison seems more likely to continue to work.

        I was thinking of something along the lines of Marshall:

        >perl -wMstrict -le "my @names = qw(FLY_ABC123_01.jpg PG_ABC123_03 SPL_ABC123_02.jpg FOO_ABC123_011 SPL_ABC123_021 SPL_ABC123_021.jpg); sub sort_123 { return map $_->[0], sort { $a->[1] <=> $b->[1] } map [ $_, m{ .* _ (\d+) }xms ], @_ ; } my @sorted = sort_123(@names); print qq{'$_'} for @sorted; " 'FLY_ABC123_01.jpg' 'SPL_ABC123_02.jpg' 'PG_ABC123_03' 'FOO_ABC123_011' 'SPL_ABC123_021' 'SPL_ABC123_021.jpg'