Как получить первый существующий каталог предков с указанием пути к файлу? - PullRequest
1 голос
/ 17 сентября 2011

В Perl, если указан путь к файлу, как найти первого существующего предка?

Например:

  • Если указан путь /opt/var/DOES/NOT/EXIST/wtv/blarg.txt и каталог /opt/var/DOES/ отсутствует, но каталог /opt/var/ есть, результат должен быть /opt/var/.
  • Если указан путь /home/leguri/images/nsfw/lena-full.jpg и каталог /home/leguri/images/nsfw/ не существует, но каталог /home/leguri/images/ существует, результатдолжно быть /home/leguri/images/.

Есть ли модуль или функция, которая делает это, или это просто вопрос разделения пути на / и проверки на существование?

Ответы [ 2 ]

5 голосов
/ 17 сентября 2011

Самое близкое, что я знаю, это Path :: Class , который делает не совсем то, что вам нужно, но может сэкономить вам пару шагов при разбиении пути.

use Path::Class 'dir';

sub get_existing_dir {
    my ( $path ) = @_;

    my $dir = dir( $path );
    while (!-d $dir) {
        $dir = $dir->parent;
    }
    return $dir->stringify;
}

my $file = '/opt/var/DOES/NOT/EXIST/wtv/blarg.txt';
my $dir = get_existing_dir( $file );
print $dir;
0 голосов
/ 17 сентября 2011

Обезьяна залатала это

#!/usr/bin/perl --
use strict;
use warnings;
use Path::Class ;

my @paths = map dir($_) , 
    map join( '/', $_, 1..6 ),
    grep defined,
    @ENV{qw/ WINDIR PROGRAMFILES TEMP HOME /},
    'Q:/bogus/drive/and/path', 
    'QQ:/bogus/drive/bogusly/treated/as/file',
    ;
push @paths, dir('bogus/relative/path/becomes/dot');
push @paths, dir('bogus/relative/path/becomes/relative/to/cwd')->absolute;

for my $path ( @paths ) {
    print $path, "\n\t=> ", $path->real_parent, "\n\n";
}

sub Path::Class::Entity::real_parent {
    package Path::Class::Entity;
    my( $dir ) = @_;
    while( !-d $dir ){
        my $parent = $dir->parent;
        last if  $parent eq $dir ; # no infinite loop on bogus drive
        $dir = $parent;
    }
    return $dir if -d $dir;
    return;
}
__END__
C:\WINDOWS\1\2\3\4\5\6
    => C:\WINDOWS

C:\PROGRA~1\1\2\3\4\5\6
    => C:\PROGRA~1

C:\DOCUME~1\bogey\LOCALS~1\Temp\1\2\3\4\5\6
    => C:\DOCUME~1\bogey\LOCALS~1\Temp

C:\DOCUME~1\bogey\1\2\3\4\5\6
    => C:\DOCUME~1\bogey

Q:\bogus\drive\and\path\1\2\3\4\5\6
    => 

QQ:\bogus\drive\bogusly\treated\as\file\1\2\3\4\5\6
    => .

bogus\relative\path\becomes\dot
    => .

C:\temp\bogus\relative\path\becomes\relative\to\cwd
    => C:\temp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...