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

i wanted to sort an array with whole file paths alphabetically.
@array = ("/media/banana.jpg","/media/Apple/apple.jpg");
i used the ff code to sort it alphabetically,
@array = sort mysort @sort; sub mysort { lc($a) cmp lc($b); }
the problem is that since 'A' goes first before 'b' "/media/Apple/apple.jpg" goes on top of the array. i wanted it to be sorted so that files that were found outside of a folder be on the top, then files in a folder at the bottom.

Replies are listed 'Best First'.
Re: Sorting Directory and Filenames
by zwon (Abbot) on Jan 10, 2009 at 17:08 UTC

    this code should do it:

    #!/usr/bin/perl use strict; use warnings; use File::Basename; my @files; while(<>) { chomp; push @files, $_; } sub fcmp { my $res = dirname($a) cmp dirname($b); $res = basename($a) cmp basename($b) unless $res; return $res; } my @sorted = sort fcmp @files; print "$_\n" for @sorted;

    Update: note that array should contain only filenames, if there are directory names it will not work correctly.

      i revised your code... because of the case-issue...
      #!/usr/bin/perl use strict; use warnings; use File::Basename; my @files; while(<>) { chomp; push @files, $_; } sub fcmp { my $res = lc(dirname($a)) cmp lc(dirname($b)); $res = lc(basename($a)) cmp lc(basename($b)) unless $res; return $res; } my @sorted = sort fcmp @files; print "$_\n" for @sorted;
        my @files; while(<>) { chomp; push @files, $_; }

        is a long winded way to say

        chomp( my @files = <> );

        And here's an alternate version that should be much faster for long lists:

        my @sorted = map /.*\0(.*)/s, sort map lc(dirname($_)) . "\0" . lc(basename($_)) . "\0" . $_, @files;