2014-02-12 4 views
0

У меня есть два значения:Построить абсолютное имя файла из файла и имя каталога

  • имя текущей директории
  • абсолютное или относительное имя файла

Мне нужно построить однозначную абсолютное filename (начиная с/и без каких-либо ../ и без ./), что соответствует доступу к этому файлу, когда каталог является текущим каталогом.

Мне нужно сделать это на Perl в Unix.

Я попытался use File::Path;, но это не работает право (ошибка?):

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

Выход:

/boot/xx 

Но он должен печатать /xx, потому что это абсолютный путь, и не должен зависеть от текущего каталога!

+2

Вы код с помощью 'Путь :: Class' и' Путь :: Class :: File', но вы говорите, что вы используете 'File: : Путь ... это немного запутанно. [Path :: Class] (http://search.cpan.org/perldoc?Path%3A%3AClass) делает документ сам по себе как слой поверх 'File :: Path'. Я думаю, ваша проблема - GIGO: Garbage In, Garbage Out. Имя файла не должно содержать косой черты; когда это происходит, вы получаете то, что получаете. Имя файла создается путем добавления списка имен каталогов (один в вашем примере) к имени файла. –

ответ

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); 
}
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(); 
+0

Id не решила проблему с ../ и ./ – porton

+0

Что вы имеете в виду? $ fileObj-> absolute - абсолютный путь к файлу без ../. – user1937198

Смежные вопросы