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

Hi there I have a text file that look something like this.
/home/users/me/proteins/1hc9.txt /home/users/me/proteins/193l.txt /home/users/me/proteins/1trz.txt /home/users/me/proteins/2psg.txt etc ...
I was wondering how to print just this from it
1hc9.txt 193l.txt 1trz.txt 2psg.txt etc
I have thought about substring but the problem with that is that its very specific isnt it, so if I changed my directories at all, I would have to modify the substring command each time. That is what I usually do, but wondered if there was a better way of doing this.
All suggestions much appreciated.

Replies are listed 'Best First'.
Re: extracting data
by Corion (Patriarch) on Nov 10, 2005 at 12:23 UTC

    The File::Basename module does what you need:

    use strict; use File::Basename; print basename $_ for <DATA>; __DATA__ /home/users/me/proteins/1hc9.txt /home/users/me/proteins/193l.txt /home/users/me/proteins/1trz.txt /home/users/me/proteins/2psg.txt
Re: extracting data
by pboin (Deacon) on Nov 10, 2005 at 12:45 UTC

    This would be a neat excuse to use negative array indexes subscripts. The split is probably not the utmost in efficiency, but it's pretty easy to write, and easier for others to understand...

    #!/usr/bin/perl use strict; while (<DATA>) { my @nodes = split ('/'); print $nodes[-1]; } __DATA__ /home/users/me/proteins/1hc9.txt /home/users/me/proteins/193l.txt /home/users/me/proteins/1trz.txt /home/users/me/proteins/2psg.txt
Re: extracting data
by g0n (Priest) on Nov 10, 2005 at 12:23 UTC
    Sounds like a job for a pattern match:

    $string =~/\/(\w+\.txt)/; print $1;

    Update: Removed \d because, as Limbic~Region pointed out in the CB, \w matches \d's as well

    --------------------------------------------------------------

    "If there is such a phenomenon as absolute evil, it consists in treating another human being as a thing."

    John Brunner, "The Shockwave Rider".

Re: extracting data
by Samy_rio (Vicar) on Nov 10, 2005 at 12:26 UTC
Re: extracting data
by Roy Johnson (Monsignor) on Nov 10, 2005 at 14:19 UTC
    The little-used rindex function is well-suited, if you don't go with a File::Basename solution. In this case, I can't think of a reason, but there might be some other situation that didn't deal with filenames where you wanted everything after the last some-character.
    my @bases = map { substr $_, 1+rindex $_, '/' } @paths;

    Caution: Contents may have been coded under pressure.
Re: extracting data
by davidrw (Prior) on Nov 10, 2005 at 13:07 UTC
    If this is the sole task of your perl script, then note that you can run any of the above solutions right from the command line (see perlrun for more details):
    perl -pe 's#.+/##' file.txt perl -MFile::Basename -pe '$_=basename $_' file.txt perl -MFile::Basename -ne 'print basename $_' file.txt perl -ne 'print ( (split("/", $_))[-1] )' file.txt perl -F/ -ane 'print $F[-1]' file.txt cut -d/ -f6 file.txt
Re: extracting data
by snowhare (Friar) on Nov 10, 2005 at 13:04 UTC
    perl -pe 's/^.*\///' test-strings.txt
Re: extracting data
by reasonablekeith (Deacon) on Nov 10, 2005 at 14:27 UTC
    I'd go with [id://Corion]'s solution, but just for completeness, here's a solution using rindex...
    perl -ne "print substr($_, rindex($_, '/') + 1)" test.data
    ---
    my name's not Keith, and I'm not reasonable.
Re: extracting data
by blazar (Canon) on Nov 10, 2005 at 14:40 UTC