Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

listing all subdirectories of directory into file

by tevolo (Novice)
on May 25, 2012 at 20:28 UTC ( #972531=perlquestion: print w/ replies, xml ) Need Help??
tevolo has asked for the wisdom of the Perl Monks concerning the following question:

Hello and thanks in advance for any assistance!!!

This is what I am trying to do which I thought would be straight forward but is causing me problems.

I am starting with a base directory that has many subdirectories under it, and those directories also have subdirectories, and I am trying to write to a file a list of all the subdirectories of any particular directory and an empty file if the directory has no subdirectories.

For instance: /about/ /about/me/ /about/you/ /about/me/myself/ would write a file in /about/ with me you a file in /you/ that is empty a file in /me/ with myself

I have tried a number of things but none are working so I am coming here for help

Thanks again for any help

Hello, I got it working. I was not returning to the find directory and that was causing the problem. Thanks for all the comments.

Here is the code, bad as it may be, for anyone else who might wish to do something similar.

#!c:/Perl/perl/bin/perl.exe use strict; use warnings; use FileHandle; use File::Find qw(find); use File::Basename; use File::Copy; use File::Find; use Cwd; my $BaseDir = 'C:/Temp3/jcr_root/content/acs/'; find( \&createContentxml, $BaseDir ); sub createContentxml { if (-d $File::Find::name) { my $dir = $File::Find::name; # print $dir . ": \n"; &subdir($dir) ; } } sub subdir { my $dir2 = getcwd; print $dir2 . "\n"; my $dir = $_[0]; chdir($dir) or warn " not able to cd into $dir \n"; print "dir: $dir: \n"; opendir DH, $dir or die "Failed to open $dir: $!"; while ($_ = readdir(DH)) { next if $_ eq "." or $_ eq ".."; if (-d $_ ) { print $_ . "\n"; open (MYFILE, '>>test7.txt'); print MYFILE $_ . "\n"; close (MYFILE); } else { next; } } open (MYFILE, '>>empty.txt'); print MYFILE " empty \n"; close (MYFILE); chdir($dir2); return 0; # Did not find any subdirectory in this directory }

Comment on listing all subdirectories of directory into file
Select or Download Code
Re: listing all subdirectories of directory into file
by jdrago999 (Pilgrim) on May 25, 2012 at 21:04 UTC
Re: listing all subdirectories of directory into file
by NetWallah (Abbot) on May 25, 2012 at 21:47 UTC
    Show us what you have tried, what you expected it to do, and how you think it failed. This will give you (and others attempting to learn from this site) a better experience.

    A slightly simpler approach than jdrago999's above is to use these built-in perl functions to achieve your objective:

    opendir, readdir, closedir.

    You will need to use the "-d" and "-f" operators to distinguish between directory names and file names. See -X for information on this.

                 I hope life isn't a big joke, because I don't get it.

      A slightly simpler approach than jdrago999's above is to use these built-in perl functions to achieve your objective:

      Do you think? I think File::Find would be the simpler approach... it does a lot for you. I'd do it something like this (untested):

      #!/usr/bin/perl use warnings; use strict; use File::Find; use Cwd qw(abs_path); sub w { -d && print $File::Find::name,$/ } File::Find::find( {wanted=>\&w}, abs_path($_)) for @ARGV;

      "My two cents aren't worth a dime.";
        I would agree that File::Find is more useful, more powerful, and more productive.

        However, it has some requirements/expectations of the user. It requires the user to understand callbacks, depth-first vs. width first, How to get the current directory name - all of which you can get if you RTFM, but IMHO, it is conceptually fairly difficult to ingest, for a newbie. That was my reasoning behind recommending 'opendir'. Also, once someone has gone through that pain, it is easier to appreciate a fine module like FF and FF:Rule.

                     I hope life isn't a big joke, because I don't get it.

        At first I thought File::Find might not be that good for this, because he wants to make a list within each directory of its subdirectories, which at first glance means "looking at" each directory twice: once when you're adding it to its parent directory's list, and then again when File::Find comes across it. But then I thought of this, which is very simple, but has the downside of opening the output file every time it needs to write a line:

        #!/usr/bin/env perl use Modern::Perl; use File::Find; sub w { if( -d $_ ){ open my $out, '>>', 'list' or die $!; print $out "$_\n"; close $out; } } File::Find::find(\&w, '.');

        Aaron B.
        Available for small or large Perl jobs; see my home node.

Re: listing all subdirectories of directory into file
by anazawa (Beadle) on May 26, 2012 at 02:01 UTC
    If you're familiar with Path::Class, I recommend for you to use Path::Class::Dir->recurse(). Create a Path::Class::Dir object as follows:
    use Path::Class qw/dir/; my $dir = dir( 'basedir' ); # platform-neutral syntax
    Once you create the object, use recurse() method:
    my @plain_files; $dir->recurse(callback => sub { my $file = shift; # Path::Class object return if $file->is_dir; push @plain_files, $file; });
    recurse() is similar to File::Find module. If you use recurse(), you can handle Path::Class::File objects in the callback subroutine.

    UPDATE: Corrected my typo ( recruse -> recurse ). Thanks to jdrago999. In addition, I noticed $file may be a Path::Class::Dir object, and so simplified my comment in the code example ( "Path::Class::File object" -> "Path::Class object" ).

      You've got a typo (recruse vs recurse) in your code example.

Re: listing all subdirectories of directory into file
by Anonymous Monk on May 26, 2012 at 08:14 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://972531]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (16)
As of 2014-07-25 14:14 GMT
Find Nodes?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:

    Results (172 votes), past polls