2011-09-17 3 views
1

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/이어야합니다.

이 작업을 수행하는 모듈 또는 기능이 있습니까? 아니면 /에 경로를 분할하고 존재 여부를 테스트해야합니까?

답변

5

내가 아는 가장 가까운 경로는 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

경로가 '/'로 시작'/ 옵션은/var /합니까/NOT/당신이 상대 완전히 가짜 제공하는 경우/WTV/blarg.txt' – Toto

+1

존재 path ('bogus/relative/path')에서, 메소드는 현재 작업 디렉토리 ('.')를 리턴하는데, 이것은 OP가 원하거나 아닐 수도 있습니다. 또한 적어도 윈도우에서'$ path'가 존재하지 않는 볼륨을 사용하면'while' 루프가 종료되지 않습니다. – FMc

0

원숭이가 패치 그것을

#!/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 
+0

스티븐의 대답에 아무런 문제없이 그 수표를 추가 할 수 있습니다. 그렇다면 원숭이 패치의 위험을 감수하려는 이유는 무엇입니까? –

관련 문제