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

Hi, Just for curiosity, Is there any way to spit the words in the directory? For example if I am at directory of /home/temp/login I would like to have a script that takes the current directory and separate the paths. use Cwd qw(); my $path = Cwd::cwd(); $path is now /home/temp/login I want to have a variable A to have /home, B = /temp C = login. Also If I want to have /home/temp/(delete the context up to the last /. How can I do that? instead of using substr("$path,-7) Thanks,

Replies are listed 'Best First'.
Re: How to split "/"
by Anonymous Monk on Apr 28, 2014 at 02:17 UTC
    See Path::Tiny
    use Path::Tiny qw/ path /; my $f = path( q(/home/temp/login)); while( not $f->is_rootdir ){ print join ' ', $f, $f->basename, "\n", ; $f=$f->parent; } __END__ /home/temp/login login /home/temp temp /home home
Re: How to split "/"
by bigj (Monk) on Apr 28, 2014 at 08:15 UTC
    A quick and dirty solution might be really to use something like my @path = split m:/:, "/home/temp/login"; Disadvantage of such a solution is that your code will break if a dirname contains a slash or you start working on Windows. If you really only want the relative dirnames, the following snippet will print them:
    use File::Basename; my $d = "/home/temp/login"; my @b = (); while ($d ne dirname($d)) { # as long as we can move up directory t +ree, when we are at root the dirname won't change any more push @b, basename($d); $d = dirname($d) } print join "\n", reverse(@b)

    Greetings,
    Janek Schleicher

    Update: Fixed a typo in script.
      A quick and dirty solution might be really to use something like my @path = split m:/:, "/home/temp/login"; Disadvantage of such a solution is that your code will break if a dirname contains a slash or you start working on Windows.

      Actually, / is not allowed in directory or file names. Windows disallows both \ and /

      FYI, Windows accepts both \ and / as separators:

      perl -e "print $ARGV[0] . ':';open(FH,$ARGV[0]) or die $ARGV[0] . ':' . $!;" dir/file.txt
        You're probably right, but I prefer defensive programming. In production code, I hate such assumptations, as there is always a chance that they will break in strange spots. Here, maybe a network drive on windows with double back slash like \\server or so might be nasty, or maybe the path might be in future something like ftp://home/temp/login. Maybe some internal stuff allows creating hidden anything with [/\\] inside, like perl allows us to create a sub "Hi with spaces inside" if we just manipulate the symbol table. I don't know for sure and won't know if something goes wrong why.

        So I try to advocate using modules that do exactly this job like File::Basename or Path::Tiny. At least, if those are much used modules, there is a lesser chance that things might go wrong.

        Of course, if I just write a snippet, I'd split m:[/\\]:, ... in a heart beat, also. No need to check a module doc if all you want is a short script that won't be used by other (persons/modules/programs).

        Greetings,
        Janek Schleicher

Re: How to split "/"
by Anonymous Monk on Apr 28, 2014 at 08:40 UTC

    Yet another way to do it with the core module File::Spec:

    my $path = "/home/temp/login"; use File::Spec; my @paths = File::Spec->splitdir($path); print "\"$_\"\n" for @paths; __END__ "" "home" "temp" "login"

    The initial empty string at $paths[0] is due to the initial slash in the path (root directory).

Re: How to split "/"
by Laurent_R (Canon) on Apr 28, 2014 at 06:08 UTC
    Or, if you want to do it yourself, you could possibly try this:
    my @paths = grep { -d} glob ("/home/temp/login/*");

      That lists the directories in the directory /home/temp/login/ (excluding ones starting with dots), but doesn't split the pathname into its components.

        Yes, you are alsolutely right. I wonder how I could misread so thoroughly the question or forget its content before I wrote my post. I should probably have had another coffee this morning before coming to the monastery.
Re: How to split "/"
by The_Ghost (Acolyte) on Apr 29, 2014 at 10:41 UTC
    Try with this ( you can use it on windows )
    my $path = '/home/temp//login' ; my ( @parts ) = ( $path =~ /([\/\\]?\w+)(?(?=[\/\\]+\w+[\/\\]*?$)[\/\\ +]+)(?=$|[\/\\])?/g ); warn Dumper \@parts ;
    Or with your variables
    my ( $a, $b , $c ) = ...