How can I extract a filename from a path using Perl?
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:
-
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 as
modifier so that.
matches newline as well:($file = $path) =~s/.*\///s;
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, $/;
Admin
Updated on July 09, 2022Comments
-
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.