Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Alternative for a directory builder

by cyber-guard (Acolyte)
on Feb 22, 2011 at 18:14 UTC ( [id://889631]=perlquestion: print w/replies, xml ) Need Help??

cyber-guard has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks

I have this script to output me all the possible directory combinations from a path:
my $a = "/aaaa/bbbb/cccc/dddd/index.html"; my ($clean_path) = $a =~ /(.*\/)/; my @dir_split = split /\//,$clean_path; my $stringer; foreach (@dir_split) { $stringer .= $_."/"; say $stringer; }

And as any perl wisdom seeker, I wonder if there is more elegant way to write this. I was messing around with map, but couldn't really get anything working...yet.

Replies are listed 'Best First'.
Re: Alternative for a directory builder
by Eliya (Vicar) on Feb 22, 2011 at 18:50 UTC

    If the order doesn't matter, you could sucessively chop off stuff from the end.  This prints the same as your code, but reversed:

    my $_=$a; say while s|[^/]+/*$||; __END__ /aaaa/bbbb/cccc/dddd/ /aaaa/bbbb/cccc/ /aaaa/bbbb/ /aaaa/ /

    But if order does matter (e.g. for mkdir purposes), you can of course also say

    my @dirs; my $_=$a; push @dirs, $_ while s|[^/]+/*$||; say for reverse @dirs; __END__ / /aaaa/ /aaaa/bbbb/ /aaaa/bbbb/cccc/ /aaaa/bbbb/cccc/dddd/
      This is really really sweet solution! Thanks a LOT. Might actually use it instead of my current code:)
Re: Alternative for a directory builder
by ikegami (Patriarch) on Feb 22, 2011 at 19:31 UTC
    A portable solution:
    use strict; use warnings; use feature qw( say ); use Path::Class qw( dir file ); my $path = "/aaaa/bbbb/cccc/dddd/index.html"; my @dir_split = file($path)->dir->dir_list(); my $dir = dir(shift(@dir_split)); for (;;) { say $dir; last if !@dir_split; $dir = $dir->subdir(shift(@dir_split)); }

    This could be shortened

    my $dir; for ( file($path)->dir->dir_list() ) { $dir = $dir ? $dir->subdir($_) : dir($_); say $dir; }

    Or mappified:

    my $dir; my @paths = map { $dir = $dir ? $dir->subdir($_) : dir($_) } file($path)->dir->dir_list();

    Path::Class

Re: Alternative for a directory builder
by atcroft (Abbot) on Feb 22, 2011 at 18:40 UTC

    I used the same idea, but File::Spec to parse the filename/directory portions when I was testing the following, which may help if you need portability later:

    use strict; use warnings; use File::Spec; my $p = q{/var/www/vhosts/testing.com/httpdocs/test1.html}; my ( $v, $d, $f ) = File::Spec->splitpath( $p ); my @dp = File::Spec->splitdir( $d ); foreach my $i ( 0 .. $#dp ) { next unless ( $i and length $dp[$i] ); print File::Spec->catdir( @dp[0 .. $i ] ), qq{\n}; }

    For my sample data, the code gave me the following output:

    Hope that helps.

    Update 2011-02-22

    I was able to come up with a map solution that seemed to work, although I believe others may have better solutions:

      which may help if you need portability later:

      You forgot to add the volume back in.

      Path::Class is easier to get right if you want portability.

      Cheers for the suggestion, however I feel reluctant using whole extra module as the script will be actually ran on web server and won't go below www dir, thus compatibility issues should be out of question
Re: Alternative for a directory builder
by ikegami (Patriarch) on Feb 22, 2011 at 19:45 UTC

    Shortest accumulator (so far?):

    local our @dirs; m{^(.*/)(?{ push @dirs, $^N })(?!)};

    In requested order:

    local our @dirs; m{^(.*?/)(?{ push @dirs, $^N })(?!)};
Re: Alternative for a directory builder
by Khen1950fx (Canon) on Feb 22, 2011 at 19:01 UTC
    Here's my stab at it:
    #!perl use 5.010; my $a = "/aaaa/bbbb/cccc/dddd/index.html"; my($clean_path) = $a =~ m[(.*/)]; my(@dir_split) = split(m[/], $clean_path); my $stringer; foreach (@dir_split) { $stringer .= $_ . "/"; say $stringer; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://889631]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2024-04-23 16:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found