根据文件名和目录名构造绝对文件名

时间:2014-02-12 14:51:38

标签: perl path directory filepath

我有两个值:

  • 当前目录名称
  • 绝对或相对文件名

我需要构造一个明确的绝对文件名(从/开始,没有任何../,没有./),这对应于在目录是当前目录时访问该文件。

我需要在Unix中的Perl中执行此操作。

我已经尝试了use File::Path;但是这样做不对(错误?):

perl -MPath::Class -e 'my $fileObj = Path::Class::File->new("/boot", "/xx"); 
                       print $fileObj->absolute, "\n";'

输出:

/boot/xx

但它应该打印/xx,因为它是一个绝对路径,它不应该依赖于当前目录!

2 个答案:

答案 0 :(得分:2)

Path::Class使用整个路径来确定文件是绝对的还是相对的,因此在示例中它是:“/ boot / xx”。输出的字符串。要解决您的问题,您需要这样的事情:

use Path::Class

my $fileObj = Path::Class::File->new("/xx");

$fileObj = Path::Class::File->new("/boot",$fileObj->relative()) if $fileObj->is_relative();

答案 1 :(得分:0)

# ("/base/path", "x") -> "/base/path/x"
# ("/base/path", "../x") -> "/base/x"
# ("/base/path", "/x") -> "/x"
sub AbsoluteNormalizedPath {
  my ($dir, $filename) = @_;
  $filename = "$dir/$filename" unless $filename =~ m{^/};
  my @components = split m{/+}, $filename;
  shift @components; # Первый компонент всегда - пустая строка, вырезаем его
  # Компоненты без ".." и ".". Работает как стек: добавляем обычные компоненты, убираем последние компонент на "..", игнорируем ".":
  my @normalizedComponents;
  foreach my $component (@components) {
    next if $component eq '.';
    if($component eq '..') {
      # В Unix parent директория корневой директории - сама корневая директория, то есть /.. - то же самое, что /
      # Так что, если список пустой - это не ошибка, оставляем его пустым (что соответсвует корневой директории).
      pop @normalizedComponents if @normalizedComponents;
    } else {
      push @normalizedComponents, $component;
    }
  }
  return '/' . join('/', @normalizedComponents);
}