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

时间:2011-01-22 11:25:36

标签: regex perl string operator-precedence

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

我试过了:

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

我是Perl的新手。

7 个答案:

答案 0 :(得分:28)

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

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

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

=~的{​​{3}}高于=

所以

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

被视为:

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

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

你想要的是:

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

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

但是这个解决方案还有很多问题:

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

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

答案 1 :(得分:3)

use File::Basename 

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

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

答案 2 :(得分:2)

我认为最好的方法是 -

use File::Basename;

my $file_name = basename($0);

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

答案 3 :(得分:1)

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)

`local mirror`_

.. _local mirror: _static/docs_mirror/index.html

答案 5 :(得分:0)

就这么简单:

$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

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

答案 6 :(得分:-2)

从路径中提取文件名对于 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”对应最后一个元素。