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

Hi all,

I'm looking for a way to read a directory structure into a script and output it into a config file. Basically read the current directory and all subdirectories and keep a list of what files are in it. The end result is a config file that I can store with a project that I can use to run a "stock" cvs checkout script that'll checkout the files and folders (and directory structure) associated with a project.

Nutshell: I'd like to generate the directory tree and stuff it into a textfile. Thanks!

Replies are listed 'Best First'.
Re: Reading directory structure?
by borisz (Canon) on Oct 12, 2004 at 17:17 UTC
    use one of the various File::Find modules. File::Find
    perl -e 'use File::Find; find( { wanted => sub { -f $_ && print $File: +:Find::name, "\n" }}, "." );'
    Boris
Re: Reading directory structure?
by muba (Priest) on Oct 12, 2004 at 17:54 UTC
Re: Reading directory structure?
by gellyfish (Monsignor) on Oct 13, 2004 at 12:22 UTC

    If you really want to eschew File::Find then you could try something like:

    #!/usr/bin/perl -w # + use strict; + + find('.'); + + sub find { my ( $dir ) = @_; + my $dh; + opendir $dh, $dir or return; + while(my $file = readdir $dh ) { next if $file =~ /^\.{1,2}$/; my $full_file = "$dir/$file"; if ( -d $full_file ) { find($full_file); } else { print "$full_file\n"; } } closedir $dh; }
    This is likely to break on a deep directory tree.

    /J\

Re: Reading directory structure?
by Grygonos (Chaplain) on Oct 12, 2004 at 20:07 UTC

    Here is some, potentially dangerous on UNIX (i.e. symlinks), code that will do what you want. I wrote this for my wife's office. It takes a given root dir, and makes an HTML "map" of it. you can modify this to fit your need. Of course the risk is that if you are on UNIX and you have a symlink, perl will open it as a directory and thusly you can potentially create an infinite loop with a symlink that links to its parent dir. Hope this code helps you out some.

    I should add, there are some win32 specifics in there that don't really divert from the premise of your idea, but if usin the exact script on unix it probably won't come out right due to some win32 specifics.

    P.S. I know the resultant HTML doesn't conform to 4.01 strict. I can make it conform but can't get the look and feel I want without breaking it (so don't harass too much for that)
      Hi Grygonos,

      While it "gets the job done", a couple things jumped out at me that I felt were important enought to comment on.

      First of all, the big one: foreach (2..$#entries) Try running this on the root of your C drive, which doesn't have the "." and ".." entries. You'll miss the first two directories.

      opendir DIR, 'c:/'; print join "\n", (readdir(DIR))[0,1]; __END__ output on my system: 2dvtllhn.sys ADOBEAPP
      Also, it seems that . and .. are always listed first in the directory, but I've never seen it documented. I certainly wouldn't depend on it.

      Second, using the -d test instead of if(opendir(TEST,$item)) to test for a directory would be more efficient as well as more readable.