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

Greetings Monks

I have the following code:
use strict; use File::Find; my $path = shift @ARGV; my @dirs; find (sub {push @dirs, $File::Find::dir}, $path); foreach my $dir (@dirs){ print "$dir\n";}
It’s meant to obtain a list of directories. However when running this script it takes ages to populate the array with entries. And most of the directories are duplicated number of times. Does any one know the reason for this and is there a better way to obtain a list of directories quicker than this very slow method.
Many Thanks in advance.

Replies are listed 'Best First'.
•Re: Retrieving a List of directories only
by merlyn (Sage) on Jul 29, 2002 at 14:28 UTC
    You're getting the directories for every file entry. You need to reject anything that isn't named "dot", then take the directory from which that's located:
    find (sub {push @dirs, $File::Find::dir if $_ eq "."}, $path);

    -- Randal L. Schwartz, Perl hacker

Re: Retrieving a List of directories only
by Abigail-II (Bishop) on Jul 29, 2002 at 14:35 UTC
    Your sub is called for each encountered file or directory. So, if a directory has 5 files in them, you push the directory 5 times on the array.

    You need something like (untested):

    find (sub {push @dirs => $File::Find::name if -d});
    The fact that it takes "ages" is that it's going to traverse your entire file hierarchy. If you have a million files, the sub will be called a million times.

    Abigail

Re: Retrieving a List of directories only
by broquaint (Abbot) on Jul 29, 2002 at 15:24 UTC
    What a wonderful excuse to use the new and oh so shiny File::Find::Rule
    use File::Find::Rule; my @dirs = find(directory => , in => shift @ARGV);
    That will find all the subdirectories the given directory.
    HTH

    _________
    broquaint

Re: Retrieving a List of directories only
by particle (Vicar) on Jul 29, 2002 at 14:42 UTC
    this accepts multiple arguments,and uses a hash to build a unique directory list.

    #!/usr/bin/perl require 5.006; use strict; use warnings; $|++; use File::Find (); my %dirs; while( $_ = shift @ARGV ) { next unless -d $_; File::Find::find sub{ -d $File::Find::name and $dirs{$File::Find::name} = undef }, $_; } print $_,$/ for sort keys %dirs;

    ~Particle *accelerates*

      Chaps and chapetts...You are all Brilliant.

      Thanks for this.

      PS : Any Chanse of help in my Drag and Drop problems,...please.