如何使用Perl从路径中提取文件名?

时间:2022-05-30 07:32:42

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.

我有一个从数据库填充的Perl变量。它的名字是$ path。我需要获取另一个变量$ file,它只包含路径名中的文件名。

I tried:

我试过了:

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

I am very new to Perl.

我是Perl的新手。

5 个解决方案

#1


26  

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

为什么重新发明*?使用File :: Basename模块:

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

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

为什么$ file = $ path = ~s /.*,///;不行?

=~ 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).

在$ path中进行替换并分配1(如果发生替换)或''(如果没有替换发生)。

What you want is:

你想要的是:

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

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

它将$ path的值赋给$ file,然后在$ 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:

    这是不正确的。基于Unix的系统中的文件名(不确定Windows)可以包含换行符。但是。默认情况下与换行符不匹配。所以你必须使用一个s修饰符。匹配换行符:

    ($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.

    最重要的是,它不是可移植的,因为它假定/是路径分隔符,而不是某些平台,如Windows(使用\),Mac(使用:)。因此,请使用该模块,让它为您处理所有这些问题。

#2


3  

use File::Basename 

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

请查看以下链接,了解其工作原理的详细说明:

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

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

#3


1  

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.

在文件和目录路径的第一个制作对象上,Path :: Class看起来似乎有些过分 - 但是它可以在复杂的脚本中获得真正的回报,并提供大量的奖励,当你通过范围蠕变进入角落时会阻止意大利面。 File :: Spec在第一个示例中用于解析路径的乐趣。

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, $/;

#4


1  

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

因此变量$ file_name将具有脚本的名称

#5


0  

$url=~/\/([^\/]+)$/;
print "Filename $1\n";

#1


26  

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

为什么重新发明*?使用File :: Basename模块:

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

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

为什么$ file = $ path = ~s /.*,///;不行?

=~ 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).

在$ path中进行替换并分配1(如果发生替换)或''(如果没有替换发生)。

What you want is:

你想要的是:

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

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

它将$ path的值赋给$ file,然后在$ 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:

    这是不正确的。基于Unix的系统中的文件名(不确定Windows)可以包含换行符。但是。默认情况下与换行符不匹配。所以你必须使用一个s修饰符。匹配换行符:

    ($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.

    最重要的是,它不是可移植的,因为它假定/是路径分隔符,而不是某些平台,如Windows(使用\),Mac(使用:)。因此,请使用该模块,让它为您处理所有这些问题。

#2


3  

use File::Basename 

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

请查看以下链接,了解其工作原理的详细说明:

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

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

#3


1  

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.

在文件和目录路径的第一个制作对象上,Path :: Class看起来似乎有些过分 - 但是它可以在复杂的脚本中获得真正的回报,并提供大量的奖励,当你通过范围蠕变进入角落时会阻止意大利面。 File :: Spec在第一个示例中用于解析路径的乐趣。

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, $/;

#4


1  

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

因此变量$ file_name将具有脚本的名称

#5


0  

$url=~/\/([^\/]+)$/;
print "Filename $1\n";