简体   繁体   English

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

[英]How can I extract a filename from a path using Perl?

I have a Perl variable I populate from the database.我有一个从数据库填充的 Perl 变量。 Its name is $path .它的名字是$path I need to get another variable $file which has just the filename from the pathname.我需要获取另一个变量$file ,它只有来自路径名的文件名。

I tried:我试过了:

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

I am very new to Perl.我对 Perl 很陌生。

Why reinvent the wheel?为什么要重新发明轮子? Use the File::Basename module:使用File::Basename模块:

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

Why did $file=$path=~s/.*\\///;为什么$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).它在$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.基于 Unix 的系统(不确定 Windows)中的文件名可以包含换行符。 But .但是. by default does not match a newline.默认情况下不匹配换行符。 So you'll have to use a s modifier so that .因此,您必须使用s修饰符,以便. 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 : ).最重要的是,它不可移植,因为它假设/是路径分隔符,这在某些平台(如 Windows(使用\\ )、Mac(使用: )时并非如此)。 So use the module and let it handle all these issues for you.因此,使用该模块并让它为您处理所有这些问题。

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

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将具有您的脚本的名称

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. Path::Class 一开始可能看起来有点矫枉过正——制作文件和目录路径的对象——但它确实可以在复杂的脚本中得到回报,并提供很多好处,当你被范围蔓延退回到角落时,它会防止出现意大利面。 File::Spec is used in the first example for fun to resolve path. 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, $/;
$url=~/\/([^\/]+)$/;
print "Filename $1\n";

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 eg https://regex101.com/ to check regular expressions.使用例如 https://regex101.com/ 来检查正则表达式。

Extracting file name from path is very easy for both Unix and Windows file systems without need any packages:从路径中提取文件名对于 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

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. Perl 允许使用从数组末尾开始的负索引。 Index "-1" corresponds to the last element.索引“-1”对应于最后一个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM