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

In a directory structure like this:

/home/www/name_of_virtual_host/logs

how would I put the third level directory names into an array?

I'm only interested in putting the directory names into the array, not the files within the directories.

  • Comment on How do I put all sub-directories into an array?

Replies are listed 'Best First'.
Re: How do I put all sub-directories into an array?
by BrowserUk (Patriarch) on Jul 23, 2002 at 08:15 UTC
Re: How do I put all sub-directories into an array?
by kodo (Hermit) on Jul 23, 2002 at 08:12 UTC
    You could use File::Find:
    use File::Find; my @DIR; my $dir = '/home/www/'; find( \&wanted , $dir); sub wanted { push(@DIRS, $File::Find::dir."/".$_) if -d $_; }
    I guess that's what you wanted right? If you don't want the absolute path just do push(@DIRS, $_) if -d $_ instead.

    giant
      Thanks

      That's almost what I want but lists all the sub-directories below /home/www.

      What I actually want is the third-level directories only i.e. the name_of_virtual_host directories only in the array, not all the directories below this level too.

      My directory structure is /home/www/name_of_virtual_host/dir4/dir5/etc.

      Can I use finddepth here to recurse down to the third level directories only?

      Wylie
        well in this case I would simply do something like:
        opendir(DIR, '/home/www/'); while (my $dir = readdir(DIR)) { print $dir; next if $dir =~ /^\.\.?$/ || ! -d $dir; push(@dirs, $dir); } closedir(DIR);
        => Code is untested but should work.

        giant
      Why flagellate yourself writing $File::Find::dir."/".$_ when there's $File::Find::name? :)

      Makeshifts last the longest.

        Historically that's what novice monks liked to do (grin).

Re: How do I put all sub-directories into an array?
by mugwumpjism (Hermit) on Jul 23, 2002 at 12:00 UTC

    This is a bit LISPy, but it will work:

    chdir "/home/www"; opendir DIR, "."; my @third_level_dirs = ( # 3. This tests for their presence grep { -d } ( # 2. This adds /logs to the end map { "$_/logs" } ( # 1. this returns all directories but . & .. grep { !/^\.\.?$/ && -d } (readdir DIR) ) ) ); closedir DIR;
      grep { !/^\.\.?$/ && -d }
      Careful: a directory called ..\n would fall through the cracks using $ as "end of string" match. You want grep { !/\A\.\.?\z/ && -d } But we don't have to use a regex for everything. grep { $_ ne '.' and $_ ne '..' and -d } ____________
      Makeshifts last the longest.

      Thanks for your help Aristotle.

      Here's what I ended up with:

      chdir "/home/www"; opendir DIR, "."; my @third_level_directories_only= ( grep { $_ ne '.' and $_ ne '..' and -d } (readdir DIR) ); closedir DIR;

      This puts the names of all my third level directories (my virtual hosts) into any array.