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

Please advise how I can get my output to eliminate the first two directories?
Currently when I print in my script:
print $variable;

I get the following:
/mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm
But only want:
test/z2.htm other/testhere.htm test/dir/z6.htm

Replies are listed 'Best First'.
Re: Changing data output
by jmcnamara (Monsignor) on Jun 19, 2003 at 15:35 UTC

    You could use substr for this:
    #!/usr/bin/perl -wl use strict; my $root = '/mydirectory/directory/'; my @files = qw( /mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm ); foreach my $file (@files) { print substr $file, length $root; } __END__ Prints: test/z2.htm other/testhere.htm test/dir/z6.htm

    You could also use index to test the string first:

    if (index($file, $root) == 0) { print substr $file, length $root; }

    --
    John.

Re: Changing data output
by helgi (Hermit) on Jun 19, 2003 at 15:52 UTC
    Or...

    my $basedir = '/mydirectory/directory/'; for (@dirs) { s/^$basedir//; print "$_\n"; }


    --
    Regards,
    Helgi Briem
    helgi DOT briem AT decode DOT is

Re: Changing data output
by Mr_Person (Hermit) on Jun 19, 2003 at 17:44 UTC
    Thought I'd throw another way out there. Take a look at File::Spec, you can use the splitpath() method to seperate the filename from the path, then use the splitdir() method to break the path apart into seperate directories. You can then just remove the first two directories (perhaps checking to make sure that they are the same directories you were expecting to remove) and put them back together with catdir(). This approach has the advantage of being cross-platform and working with different directory names easily.
Re: Changing data output
by Willard B. Trophy (Hermit) on Jun 19, 2003 at 15:53 UTC
    ... or you could split the strings into an array on the directory separators, and join them back together, using only the third and fourth entries:
    #!/usr/bin/perl -wl while (<DATA>) { chomp; print join ( '/', ( split ( '/', $_ ) )[ 3, 4 ] ); } exit; __DATA__ /mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm

    Of course, I'm sure there's a nicer way of being able to specify "from the third entry onwards", but I was never very good with arrays.

    --
    bowling trophy thieves, die!

Re: Changing data output
by artist (Parson) on Jun 19, 2003 at 15:39 UTC
    Assuming the first 2 directories are always starting from root and not the same all time, this code would be useful.
    @files = qw(/mydirectory/directory1/test/z2.htm /mydirectory/directory2/other/testhere.htm /mydirectory1/directory/test/dir/z6.htm); s[/.*?/.*?/][] for @files; print join "\n", @files;
    artist
Re: Changing data output
by KPeter0314 (Deacon) on Jun 19, 2003 at 15:49 UTC
    Or you could use a regexp substitution....as usual TMTOWTDI

    my @files = qw( /mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm ); foreach ( @files ) { s/^(\/\w+\/\w+\/)//; print "$_\n"; }
    Updated explanation: This regexp will match any words as the first two directories and remove them. If you have specific directories in mind, replace each \w+ with the directory names you want removed.

    -Kurt

Re: Changing data output
by kutsu (Priest) on Jun 19, 2003 at 15:37 UTC

    Try substr for more information.

    my $string = "/mydirectory/directory/test/z2.htm"; my $foo = substr($string, 23, 100); print $foo;

    Update: Man you people are fast

    "Pain is weakness leaving the body, I find myself in pain everyday" -me

Re: Changing data output
by nekron99_ (Acolyte) on Jun 19, 2003 at 16:06 UTC
    a regex substitute would also work
    foreach my $file ( @LIST ) { $file =~ s/^\/mydirectory\/directory\//; next; }
Re: Changing data output
by kral (Monk) on Jun 20, 2003 at 08:01 UTC
    You can also use the map way:
    use strict; use warnings; my $root = "/mydirectory/directory"; my @files = qw(/mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm ); map( s/$root//, @files ); foreach (@files) { print "$_\n"; }
    ------------
    ..::KRaL::..
    (sorry for my english)
Re: Changing data output
by bm (Hermit) on Jun 19, 2003 at 16:07 UTC
    And here is Yet Another Way using grep

    @files = qw(/mydirectory/directory/test/z2.htm /mydirectory/directory/other/testhere.htm /mydirectory/directory/test/dir/z6.htm ); my $root = '/mydirectory/directory/'; my @paths = grep s#$root##, @files; print "$_\n" for @paths;
      grep is not a good solution for this problem. grep modifies the list in-place, then makes a copy for @paths. You end up with two (hopefully)* identical arrays.

      *If the match fails, that element will not be returned by grep, so will not be in @paths!