File :: Basename的文档说
NOTE: "dirname()" and "basename()" emulate the behaviours, and quirks,
of the shell and C functions of the same name. See each function's
documentation for details.
这些怪癖是什么?
答案 0 :(得分:1)
每个函数的man
页面都记录了这个怪癖:
man dirname
说明
打印NAME,删除其尾随/组件;如果NAME包含 不,输出'。' (意思是 当前目录)。
示例
dirname /usr/bin/sort Output "/usr/bin". dirname stdio.h Output ".".
man basename
<强>描述强>
使用任何首要目录打印NAME 组件已删除。如果指定, 同时删除一个尾随的SUFFIX。
示例
basename /usr/bin/sort Output "sort". basename include/stdio.h .h Output "stdio".
答案 1 :(得分:1)
实际上,这些怪癖记录在Perl函数本身的文档中。 http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#basename
提供此功能是为了与Unix shell兼容 命令basename(1)。它并不总是返回文件名部分 你可能期望的路径... basename()返回最后一级 即使最后一级是明确的目录,也是文件路径的。 ......还有 请注意,为了与shell命令兼容,basename() 如果后缀与剩余的相同,则不会删除后缀 文件名中的字符。
换句话说,basename("dir/")
是"dir/"
,而不是""
; basename("dir/.txt", ".txt")
为".txt"
,而不是""
。
http://search.cpan.org/~rjbs/perl-5.16.0/lib/File/Basename.pm#dirname
dirname
的怪癖非常奇怪,取决于$File::Basename::Fileparse_fstype
的当前值。我会在这里粘贴代码,因为它很短。
sub dirname {
my $path = shift;
my($type) = $Fileparse_fstype;
if( $type eq 'VMS' and $path =~ m{/} ) {
# Parse as Unix
local($File::Basename::Fileparse_fstype) = '';
return dirname($path);
}
my($basename, $dirname) = fileparse($path);
if ($type eq 'VMS') {
$dirname ||= $ENV{DEFAULT};
} elsif ($type eq 'MacOS') {
if( !length($basename) && $dirname !~ /^[^:]+:\z/) {
_strip_trailing_sep($dirname);
($basename,$dirname) = fileparse $dirname;
}
$dirname .= ":" unless $dirname =~ /:\z/;
} elsif (grep { $type eq $_ } qw(MSDOS DOS MSWin32 OS2)) {
_strip_trailing_sep($dirname);
unless( length($basename) ) {
($basename,$dirname) = fileparse $dirname;
_strip_trailing_sep($dirname);
}
} elsif ($type eq 'AmigaOS') {
if ( $dirname =~ /:\z/) { return $dirname }
chop $dirname;
$dirname =~ s{[^:/]+\z}{} unless length($basename);
} else {
_strip_trailing_sep($dirname);
unless( length($basename) ) {
($basename,$dirname) = fileparse $dirname;
_strip_trailing_sep($dirname);
}
}
$dirname;
}
# Strip the trailing path separator.
sub _strip_trailing_sep {
my $type = $Fileparse_fstype;
if ($type eq 'MacOS') {
$_[0] =~ s/([^:]):\z/$1/s;
} elsif (grep { $type eq $_ } qw(MSDOS DOS MSWin32 OS2)) {
$_[0] =~ s/([^:])[\\\/]*\z/$1/;
} else {
$_[0] =~ s{(.)/*\z}{$1}s;
}
}