Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Your skill will accomplish
what the force of many cannot

Traversing directories recursively

by jesuashok (Curate)
on Nov 20, 2007 at 09:37 UTC ( #651889=perlquestion: print w/ replies, xml ) Need Help??
jesuashok has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,
#!/usr/bin/perl use strict; print_dir ( "." ); sub print_dir { my $dir_name = shift; #print "-->$dir_name\n"; opendir ( my $dir_h , "$dir_name") or die "Unale to open dir :$dir_ +name: $!\n"; #print "Inside Function\n"; while ( my $file = readdir($dir_h) ) { #print "File :$file:\n"; next if ( "$dir_name/$file" =~ /\/\.$/ or "$dir_name/$file" =~ /\ +/\.\.$/ ); #print "$dir_name\n"; #<>; if ( -d "$dir_name/$file" ) { #print "Match\n"; print_dir ( "$dir_name/$file" ); } print "$dir_name/$file\n"; } #return $dir_name; }
I am trying to print the contents of a directory recursively. But I see in the output that the files are printed-out 2 times. Is there anything I am missing out in the recursive function.

i m possible

Comment on Traversing directories recursively
Download Code
Re: Traversing directories recursively
by andreas1234567 (Vicar) on Nov 20, 2007 at 10:06 UTC
    Works for me:
    $ mkdir foo bar $ touch bar/1 $ touch bar/2 $ touch bar/3 $ touch foo/4 $ touch foo/5 $ touch foo/6 $ mkdir -p bar/tze $ touch bar/tze/7 $ touch bar/tze/8 $ touch bar/tze/9 $ perl -w | sort | uniq -c 1 ./ 1 ./bar 1 ./bar/1 1 ./bar/2 1 ./bar/3 1 ./bar/tze 1 ./bar/tze/7 1 ./bar/tze/8 1 ./bar/tze/9 1 ./foo 1 ./foo/4 1 ./foo/5 1 ./foo/6
    I'd rather use File::Find:
    $ perl -wle 'use strict; use File::Find; find(sub { print if -f }, "." +);' 1 3 2 8 7 9 6 5 4
Re: Traversing directories recursively
by grinder (Bishop) on Nov 20, 2007 at 10:15 UTC

    Use the CPAN, Luke.

    #! /usr/bin/perl use strict; use warnings; use File::Find::Rule; my $start = shift || '.'; for my $obj (File::Find::Rule->in($start)) { print "$obj\n"; }

    The key word in the module name is "Rule". You can add rules to restrict what is returned: files only, smaller or larger than a given size, belonging to foo, modified no more than 3 weeks ago, is read-only and so forth.

    Get your rules right, and your own code becomes very simple.

    • another intruder with the mooring in the heart of the Perl

Re: Traversing directories recursively
by Erez (Curate) on Nov 20, 2007 at 10:16 UTC
    Works for me. I would repeat the usual steps to ease the pain of finding what's not working,
    use warnings as well as strict, use File::Find module instead of writing your own recursion, and some other perlisms.

    Software speaks with tongues of man; I debug, therefore I code.

Re: Traversing directories recursively
by johngg (Abbot) on Nov 20, 2007 at 10:33 UTC
    By choosing a different regex delimiter and using a ? (0 or 1) quantifier you can make this line

    next if ( "$dir_name/$file" =~ /\/\.$/ or "$dir_name/$file" =~ /\/\.\. +$/ );

    simpler and more readable

    next if "$dir_name/$file" =~ m{/\.\.?$};



Re: Traversing directories recursively
by RaduH (Scribe) on Nov 20, 2007 at 20:19 UTC
    Try this:
    sub browse($) { my $path = $_[0]; #append a / if missing if($path !~ /\/$/) { $path .= '/'; } #loop through the files contained in the directory for my $eachFile (glob($path.'*')) { #if the file is a directory if(-d $eachFile) { #browse directory recursively browse($eachFile); } else { your file processing here } } }#browse
    It seems shorter (if you ignore/eliminate the makeup I added to enhance readability) and much simpler than what you have and works. Hope this helps.
      Nice for a programming exercise. But one should should not reinvent the wheel. I'd use something that =~ m/File::Find(?:::Rule)?$/ :-)


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2014-04-19 22:51 GMT
Find Nodes?
    Voting Booth?

    April first is:

    Results (485 votes), past polls