2013-05-04 1 views
1
my $directory = shift @_; 
    my @dh; 
    my @files; 

    opendir (my $dh, $directory) or die "Couldn't open dir '$directory' : $!"; 
    foreach my $file(readdir $dh) { 
     if(-f $file =~ /\.htm$/){ 
        push(@files,$file); 
     } 
     elsif(-d $file){ 
      push(@dh,$file); 
      $dh = shift @dh; 
     } 

     closedir ($dh); 
    } 

예를 들어 스크립트를 경로로 가져 오려고합니다. DATA/(성공)입니다. 그러나 스크립트에서 해당 디렉토리 및 하위 디렉토리를 스캔 한 다음 일치하는 파일이 있으면 @files에 저장됩니다.디렉토리를 열고 일치하는 파일을 찾기 위해 상위 디렉토리를 검색합니다.

루프를 사용하여 모든 하위 폴더를 검사하려고합니다. 예 : 이 문장에서

elsif(-d $file){ 
    push(@dh,$file); 
    $dh = shift @dh; 
} 

$dh 내가 Segmentation fault

+0

이것은 이미 작성한 코드를 사용하는 것 중 하나입니다. File :: Find는 핵심 Perl이거나 File :: Next는 CPAN을 통해 쉽게 설치됩니다. –

답변

3

여기에 몇 가지 문제가 있습니다 얻고 그러나 새 하위 디렉토리 이름이

를 스캔 얻을 것이다 :

  • readdir 반환 의사 디렉토리 ...이 무시되어야합니다.

  • readdir은 파일의 전체 경로가 아니라 파일 이름 만 반환합니다. 그래서 -f-d이 이름의 항목에 대한 현재 작업 디렉토리에서 찾게됩니다 아마도에 갈되지 않는, 그것을 떨어져 $dh 처리가

  • 당신은 @dh에 디렉토리 이름을 추진하고 있지만, 디렉토리를 이동하는 찾을 수 없습니다 작동

  • 시험 -f $file =~ /\.htm$/ 제는 $file 변수 정규식을 적용하고 -f 파라미터로서 (또는 1"" 중) 그 결과를 이용한다. 즉, 하나를 발견하면 현재 디렉토리의 나머지 부분은

상황을 처리하지 않을 있도록, 당신은 즉시 새 디렉토리를 처리로 이동하는 모든

  • 에서 원하는 아니다 이 같은 정상적으로 File::Find 또는 재귀 서브 루틴을 사용하여 수행되지만 꼬리 재귀를 제거하여 이런 식으로 할 수 있습니다. 참고 디렉토리 링크를 고려하지 않고 끝없이 반복 될 수 있습니다. 이런 이유로 모든 꼬임이 다림질 된 모듈을 사용하는 것이 가장 좋습니다.

    use strict; 
    use warnings; 
    
    my @dh = @_; 
    my @files; 
    
    while (@dh) { 
    
        my $directory = shift @dh; 
        opendir my $dh, $directory or die "Couldn't open dir '$directory' : $!"; 
    
        while (readdir $dh) { 
        next if /\A\.\.?\z/; 
        my $node= "$directory/$_"; 
    
        if (-f $node and /\.html?$/i) { 
         push @files, $node; 
        } 
        elsif (-d $node) { 
         push @dh, $node; 
        } 
        } 
    
    } 
    
  • +0

    코드'next if /\A\.\.?\z/;를 설명해 주시겠습니까? my $ node = "$ directory/$ _";'어떻게 작동하는지 잘 모르겠다. ( –

    +0

    정규 표현식'\ A'는 문자열의 시작 부분과 일치하며'\ .'는 점 '\.?'과 일치한다. '\ z'는 문자열의 끝과 일치합니다. 그래서 전체 패턴은 정확히 하나 또는 두 개의 점을 포함하는 문자열과 일치합니다. 할당은 현재 디렉토리와 현재 파일 이름을 중간에 슬래시와 결합하고 puts 결과를'$ node'에 저장합니다. – Borodin

    관련 문제