我在Unix系统上使用File::Spec来获取文件的绝对路径:
use File::Spec::Functions qw(:ALL);
use strict;
use warnings;
use feature qw(say);
my $file = "../../this/is/a/test";
say rel2abs($file);
打印出/directory/to/program/../../this/is/a/test
。我希望打印出/directory/this/is/a/test
。
我看到了no_upwards
方法,这里是描述:
Given a list of file names, strip out those that refer to a parent directory.
(Does not strip symlinks, only '.', '..', and equivalents.)
@paths = File::Spec->no_upwards( @paths );
但是,这似乎不起作用。相反,我查看了File :: Spec模块中的代码,发现了这个:
sub no_upwards {
my $self = shift;
return grep(!/^\.{1,2}\z/s, @_);
}
那么,这种方法做了什么,以及如何让它起作用?
如果我正确阅读,则会获取目录列表,然后删除所有.
或..
的目录。 (根据Perldoc \z
表示仅在字符串末尾匹配)。
是否有 平台独立的 折叠这些特殊目录的方法? no_upwards
假设要做什么,以及如何使用它?我试过了:
say no_upwards(rel2abs($file));
我应该使用另一种方法吗?
答案 0 :(得分:8)
在canonpath的File::Spec文档中,它说:
方法
canonpath
不对文件系统进行物理检查,而是对路径进行逻辑清理。
$cpath = File::Spec->canonpath( $path ) ;
请注意,这会将不折叠
x/../y
部分转换为y
。这是 按设计。如果您系统上的/foo
是/bar/baz
的符号链接,那么/foo/../quux
实际上是/bar/quux
,而不是/quux
是一个天真的../
- 删除 会给你的。如果你想做这种处理,你 可能希望Cwd的realpath()函数实际遍历 文件系统清理这样的路径。
所以我会考虑使用Cwd的realpath()函数,就像它说的那样。
答案 1 :(得分:2)
回答你的问题
那么,这种方法做了什么,以及如何让它起作用?
当你在终端上ls -a
时,它会给你类似的东西
. .. some_folder some_file.txt another_file.txt
no_upwards()
只需删除.
和..
并返回列表
some_folder some_file.txt another_file.txt