vonman has asked for the wisdom of the Perl Monks concerning the following question:

I have an array loaded with a variety of filenames. The following are examples of the filenames.
Order_29May11:05.bak Order_11Jun20:25.bak Order_10Jun14:16.bak Order_10Jun16:04.bak
I would like to be able to sort the array by time. And as you can see from the filenames months,dates, and times need to be taken into consideration. Any bright ideas? Thanks much in advance. Rich

Replies are listed 'Best First'.
Re: How can I sort this array?
by dws (Chancellor) on Jun 17, 2002 at 17:32 UTC
    To get these to sort, you're going to need to extract/construct a key you can sort on. Since the files are named like   Order_29May11:05.bak You can extract some sortable pieces by doing
    $name =~ s/_(\d\d)(...)(\d\d:\d\d)/; $key = $month{$2} . $1 . $3;
    where %month is a hash that maps the 3 character month abbreviation to a to character numeric string (e.g., 'Jan' => '01', ... 'Dec' => '12').

    You can use this within a Schwartzian transform (many examples of which can be found by doing a Super Search on "Schwartzian").

Re: How can I sort this array?
by RMGir (Prior) on Jun 17, 2002 at 17:34 UTC
    I think you should probably look at Date::Manip.

    You'd have to break out the dates from each filename and parse them before you do your search, so you'd definitely want to set up a Schwartzian Transform so you don't redo the parse for each comparison...

Re: How can I sort this array?
by flounder99 (Friar) on Jun 17, 2002 at 19:24 UTC
    Time::Local is core and faster than Date::* functions

    use Time::Local qw( timelocal ); use strict; my @input = reverse qw( Order_29May11:05.bak Order_11Jun20:25.bak Order_10Jun14:16.bak Order_10Jun16:04.bak ); # reversed to prove it works since they are already sorted my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); my %months; for (0 .. $#months) {$months{$months[$_]} = $_} # merlyn's definition of the # Schwartzian Transform # changed to numerical sort my @output = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [$_, expensive_func($_)] } @input; print join "\n", @output; exit; sub expensive_func { # convert filename to date $_[0] =~ /Order_(\d+)(...)(\d+):(\d+)\.bak/ or die "bad filename $_[0]"; return timelocal(0, $4, $3, $1, $months{$2}, 0); } __OUTPUT___ Order_29May11:05.bak Order_10Jun14:16.bak Order_10Jun16:04.bak Order_11Jun20:25.bak
    -- flounder