How can I extract a filename from a path using Perl?

41,919

Solution 1

Why reinvent the wheel? Use the File::Basename module:

use File::Basename;
...
$file = basename($path);

Why did $file=$path=~s/.*\///; not work?

=~ has higher precedence than =

So

$file = $path =~s/.*\///;

is treated as:

$file = ($path =~s/.*\///);

which does the replacement in $path and assigns either 1 (if replacement occurs) or '' (if no replacement occurs).

What you want is:

($file = $path) =~s/.*\///;

which assigns the value of $path to $file and then does the replacement in $path.

But again there are many problems with this solution:

  1. It is incorrect. A filename in Unix based systems (not sure about Windows) can contain newline. But . by default does not match a newline. So you'll have to use a s modifier so that . matches newline as well:

    ($file = $path) =~s/.*\///s;
    
  2. Most importantly it is not portable as it is assuming / is the path separator which is not the case with some platforms like Windows (which uses \), Mac (which uses :). So use the module and let it handle all these issues for you.

Solution 2

use File::Basename 

Check the below link for a detailed description on how it works:

http://p3rl.org/File::Basename

Solution 3

I think the best way of doing this is -

use File::Basename;

my $file_name = basename($0);

So the variable $file_name will have the name of your script

Solution 4

Path::Class may seem like overkill at first—making objects of file and dir paths—but it can really pay off in complicated scripts and offers lots of bonuses that will prevent spaghetti when you get backed into a corner by scope creep. File::Spec is used in the first example for fun to resolve path.

use warnings;
use strict;
use Path::Class qw( file );
use File::Spec;

# Get the name of the current script with the procedural interface-
my $self_file = file( File::Spec->rel2abs(__FILE__) );
print
    " Full path: $self_file", $/,
    "Parent dir: ", $self_file->parent, $/,
    " Just name: ", $self_file->basename, $/;

# OO                                    
my $other = Path::Class::File->new("/tmp/some.weird/path-.unk#");
print "Other file: ", $other->basename, $/;
Share:
41,919
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a Perl variable I populate from the database. Its name is $path. I need to get another variable $file which has just the filename from the pathname.

    I tried:

    $file = $path =~ s/.*\///;
    

    I am very new to Perl.