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

发布于 2024-10-13 01:40:08 字数 183 浏览 3 评论 0原文

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

我尝试过:

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

我对 Perl 很陌生。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

何其悲哀 2024-10-20 01:40:08

为什么要重新发明轮子?使用 File::Basename 模块:

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

为什么 $file=$path= ~s/.*\///; 不起作用?

=~优先级 高于=

因此

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

被视为:

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

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

您想要的是:

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

$path 的值分配给 $file,然后在 $path 中进行替换。

但这个解决方案同样存在很多问题:

  1. 它是不正确的。基于 Unix 的系统(不确定 Windows)中的文件名可以包含换行符。但 . 默认情况下不匹配换行符。因此,您必须使用 s 修饰符,以便 . 也匹配换行符:

    ($file = $path) =~s/.*\///s;
    
  2. 最重要的是,它不可移植,因为它假设 /< /code> 是路径分隔符,而某些平台则不然,例如 Windows(使用 \)、Mac(使用 :)。因此,请使用该模块并让它为您处理所有这些问题。

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.

倾其所爱 2024-10-20 01:40:08
use File::Basename 

检查以下链接以获取有关其工作原理的详细说明:

http://p3rl.org/File::Basename< /a>

use File::Basename 

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

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

吐个泡泡 2024-10-20 01:40:08

我认为最好的方法是 -

use File::Basename;

my $file_name = basename($0);

所以变量 $file_name 将具有脚本的名称

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

请爱~陌生人 2024-10-20 01:40:08

就这么简单:

$path =~ /.*[\/\\](.*)/;    # will return 1 (or 0) and set $1
my $file = $1;              # $1 contains the filename

要检查文件名是否可用,请使用:

$file = $1 if $path =~ /.*[\/\\](.*)/;

模式:

.*[\/\\](.*)
| |     |
| |     \- at last there is a group with the filename
| \------- it's the last / in linux or the last \ in windows
\--------- .* is very greedy, so it takes all it could

使用例如 https://regex101.com/ 进行检查正则表达式。

As easy as that:

$path =~ /.*[\/\\](.*)/;    # will return 1 (or 0) and set $1
my $file = $1;              # $1 contains the filename

To check if an filename is available use:

$file = $1 if $path =~ /.*[\/\\](.*)/;

The pattern:

.*[\/\\](.*)
| |     |
| |     \- at last there is a group with the filename
| \------- it's the last / in linux or the last \ in windows
\--------- .* is very greedy, so it takes all it could

Use e.g. https://regex101.com/ to check regular expressions.

悸初 2024-10-20 01:40:08

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

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, $/;
耀眼的星火 2024-10-20 01:40:08
$url=~/\/([^\/]+)$/;
print "Filename $1\n";
$url=~/\/([^\/]+)$/;
print "Filename $1\n";
━╋う一瞬間旳綻放 2024-10-20 01:40:08

对于 Unix 和 Windows 文件系统来说,从路径中提取文件名非常容易,不需要任何包:

my $path;
$path = 'C:\A\BB\C\windows_fs.txt';     # Windows
#$path = '/a/bb/ccc/ddd/unix_fs.txt';    # Unix

my $file =  (split( /\/|\\/, $path))[-1];
print "File: $file\n";

# variable $file is "windows_fs.txt"  for Windows
# variable $file is "unix_fs.txt"     for Unix

逻辑非常简单:创建一个包含路径所有元素的数组并检索最后一个元素。 Perl 允许使用从数组末尾开始的负索引。索引“-1”对应于最后一个元素。

Extracting file name from path is very easy for both Unix and Windows file systems without need any packages:

my $path;
$path = 'C:\A\BB\C\windows_fs.txt';     # Windows
#$path = '/a/bb/ccc/ddd/unix_fs.txt';    # Unix

my $file =  (split( /\/|\\/, $path))[-1];
print "File: $file\n";

# variable $file is "windows_fs.txt"  for Windows
# variable $file is "unix_fs.txt"     for Unix

The logic is very simple: create an array of all elements making the path and retrieve the last one. Perl allows to use negative indexes starting from end of the array. Index "-1" corresponds to the last element.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文