I wasn't clear from your post if portability was an issue. Your sample data lists *nix style file names but your point of reference is "Windows Explorer". If so, the answers given so far assume *nix file naming conventions and may not be portable. For portable solutions, you'll need to use File::Spec.

Here is an example showing how to use it. In addition to the sorting it also calculates the information needed to properly indent names "like Windows Explorer":

use strict; use warnings; use File::Spec; my @arr = ( { 'path' => '/c/', dir => '/' }, { 'path' => '/c/a1.mp3', 'file' => 1, 'dir' => '/c' }, { 'path' => '/c/a2.mp3', 'file' => 1, 'dir' => '/c' }, { 'path' => '/c/bb/aa1.mp3', 'file' => 1, 'dir' => '/c/bb' }, { 'path' => '/c/bb/aa2.mp3', 'file' => 1, 'dir' => '/c/bb' }, { 'path' => '/c/bb/', 'dir' => '/c' }, { 'path' => '/c/cc/', 'dir' => '/c' }, { 'path' => '/c/aa/', 'dir' => '/c' } ); my $TAB_WIDTH=3; my $FORMAT="%-30s%s\n"; #----------------------------------------- # The sorting function #----------------------------------------- sub parsePathPortably { my $hPathInfo = shift; my $sPath = $hPathInfo->{path}; my $bFile = $hPathInfo->{file}; my ($sVol, $sDir, $sLocal) = File::Spec->splitpath($sPath, !$bFile); # File::Spec->splitdir assumes $dir is a relative path # without this line the first element of @aDirs on *nix is # an empty directory (because nothing is before root) my $sRelPath = File::Spec->abs2rel($sDir, File::Spec->rootdir()); my @aDirs =File::Spec->splitdir($sRelPath); # get indentation level and local file name my $iDepth = scalar(@aDirs); unless ($bFile) { $iDepth--; $sLocal = pop @aDirs; } # reconstruct the path, but before each directory name # segment insert 0x000 and before each file name segment # insert 0x001. It is important to insert something # before *all* directory name elements to insure # that the "b" segment of /a/b/c and /a/b sort properly # # we also insert before file names on the off,off chance # that you run into a file system where there is a file # name that begins with 0x000. DOS and most *nix systems # prohibit 0x000 in file names, but not all # - see [Wikipedia://Filename] for a list of OS's where # 0x000 does not appear to be in the list of reserved or # prohibited characters, among them: OS2, various Mac OS's my $k = File::Spec->catpath ($sVol, File::Spec->catdir(map{ord(0).$_} @aDirs) , ord($bFile ? 1 : 0) . $sLocal); return $k => [ $iDepth, $sPath, $sLocal ]; } #-------------------------------------------------- # Demonstration of how to use the sorting function #-------------------------------------------------- my $hPaths = { map { parsePathPortably($_) } @arr }; foreach my $k (sort keys %$hPaths) { my ($iDepth, $sPath, $sLocal) = @{$hPaths->{$k}}; my $sIndent = ' ' x ($TAB_WIDTH*$iDepth); printf($FORMAT, "$sIndent$sLocal", $sPath); }

This produces the following output:

c /c/ aa /c/aa/ bb /c/bb/ aa1.mp3 /c/bb/aa1.mp3 aa2.mp3 /c/bb/aa2.mp3 cc /c/cc/ a1.mp3 /c/a1.mp3 a2.mp3 /c/a2.mp3

In reply to Re: sorting tree with folders on top by ELISHEVA
in thread sorting tree with folders on top by diweooy

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.