我需要从完整的文件路径获取文件的名称。我试过用:
$out_fname =~ s/[\/\w+\/]+//;
但是它“吃掉了”文件名的文字。
示例:
表示文件:
/bla/bla/folder/file.part.1.file
,
它返回:
.part.1,file
答案 0 :(得分:15)
你可以这样做:
use File::Basename;
my $path = "/bla/bla/folder/file.part.1.file";
my $filename = basename($path);
答案 1 :(得分:5)
除了File :: Basename之外,还有Path::Class,它可以用于更复杂的操作,特别是在处理目录或跨平台/文件系统操作时。在这种情况下,它可能有点过分,但可能值得了解。
use Path::Class;
my $file = file( "/bla/bla/folder/file.part.1.file" );
my $filename = $file->basename;
答案 2 :(得分:4)
我同意其他答案,但只想解释你的模式中的错误。正则表达式很棘手,但值得学习。
方括号定义了一类匹配的对象。在您的情况下,它将与正斜杠,单词字符(来自\w
),+
字符或正斜杠字符(这是多余的)匹配。然后你要说的是匹配其中的一个或多个。有多个字符串可以匹配。它将匹配最早的起始角色,因此第一个/
。然后它会尽可能地抓住。
这不是你想要的清楚。例如,如果您的某个目录名中有.
,则会停在那里。 /blah.foo/bar/x.y.z
会返回.foo/bar/x.y.z
。
想到这一点的方法是,您希望匹配所有字符,包括最终/
。
然后所有字符都为斜杠:/.*\//
但为了更安全,请在前面添加一个插入符号,以确保它从那里开始:/^.*\//
要允许前向和反斜杠,请为其创建一个类:/^.*[\/\\]/
(即elusive's answer)。
真正的好参考是Learning Perl。有大约3个非常好的正则表达式章节。它们也适用于非Perl正则表达式用户。
答案 3 :(得分:1)
在目录分隔符上使用split
是另一种选择。这与使用正则表达式有相同的注意事项(即使用文件名,最好使用其他人已经考虑边缘情况,可移植性,不同文件系统等的模块,因此您不需要在后退和前进上进行匹配-slashes),但作为另一种通用技术很有用,你有一个带有重复分隔符的字符串。
my $file = "/bla/bla/folder/file.part.1.file";
my @parts = split /\//, $file;
my $filename = $parts[-1];
答案 4 :(得分:1)
这是完全我希望它在给定的替换中保留。你是说用什么都不替换最长的斜杠和单词字符串。因此它会抓取所有角色,直到你没有指定的第一个角色并删除它们为止。
它正在做你要求它做的事情。我和其他人一起使用File::Basename
来说明你要做的事情。
但这是做同样事情的最快方法:
my $fname = substr( $out_fname, rindex( $out_fname, '/' ) + 1 );
在这里,它说在字符串中找到{em> last 出现的'/'
并给我在该位置后面开始的文本。我不是一直反对正则表达式,但它只是表达你真正想做的事情。我不得不长时间做这样的事情,我写了一个last_after
子:
sub last_after {
my ( $string, $delim ) = @_;
unless ( length( $string ) and my $ln = length( $delim )) {
return $string // '';
}
my $ri = rindex( $string, $delim );
return $ri == -1 ? $string : substr( $string, $ri + $ln );
}
答案 5 :(得分:0)
我还需要从一堆路径名中拉出最后一个字段。这对我有用:
grep -o '/\([^/]*\)$' inputfile > outputfile
答案 6 :(得分:-1)
这个怎么样:
$out_fname =~ s/^.*[\/\\]//;
它应该删除文件名前面的所有内容。