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

Hi fellow monks,

> I'm trying to use the following piece of code to get all files in a given directory. What I would like to achieve now is to output the files in THE SAME ORDER as "ls -R" would do.
@DirArray should hold the directories. %Songs the files in a given subdir.
The Problem is, that the contents of @DirArray doesn't have the same order as an "ls -R" output would have. The Information about the directory sequence is lost (I suppose it's because file::find sorts by inodes).

Is there any possibility to use file::find here or do I have to write my own implementation of it?

any hints appreciated,

Bjoern

my %option = (); my %Songs =(); my @DirArray; my $DirIndex==0; my $CurrentDir; my $Artist; my $Index=1; getopts("d:", \%option); sub produce_array { if (-d $_) { $CurrentDir=$_; $DirArray[$DirIndex]=$_; $DirIndex++; }; if (-f $_) { push (@{$Songs{$CurrentDir}},$_); }; } find (\&produce_array, $option{d});

Replies are listed 'Best First'.
Re: file::find and ordered output
by broquaint (Abbot) on May 13, 2002 at 09:15 UTC
    An option would be to munge your data before it gets passed to the produce_array() function with the preprocess option
    find({ wanted => \&produce_array, preprocess => \&munge_data, }, $option{d});
    See the File::Find manpage for more detail.
    HTH

    _________
    broquaint

      I had a look at the manpage (it wasn't the first ;-) but couldn't quite understand how this (preprocess) would help me in my problem.

      quoting the man page of "file::find => preprocess"

      The value should be a code reference. This code reference is used to preprocess the current directory. The name of currently processed directory is in $File::Find::dir. Your preprocessing function is called after readdir() but before the loop that calls the wanted() function. It is called with a list of strings (actually file/directory names) and is expected to return a list of strings. The code can be used to sort the file/directory names alphabetically, numerically, or to filter out directory entries based on their name alone. When follow or follow_fast are in effect, preprocess is a no-op.

      "This code reference is used to preprocess the current directory."

      How can it affect the order of the directory processing?

      pondering

      Bjoern
        How can it affect the order of the directory processing?
        Its effect is that it changes what is passed to the wanted() coderef e.g
        find({ preprocess => sub { return sort { $b cmp $a } @_ }, wanted => \&process_array, }, @ARGV);
        This will sort the directory listing that process_array() gets in reverse alphabetic order. So basically the preprocess option allows you to change what the wanted() function receives from changing it's order to removing unwanted directory entries.
        HTH

        _________
        broquaint

        update: changed <=> to cmp in the sort() (thanks ariels)