2013-05-08 3 views
0

나는 ~ 5000 2,400 크기의 .txt 파일을 저장하는 디렉토리가 있습니다.Perl - 첫 번째 파일 (.txt) 만 가져 오지 않고 다른 디렉토리의 파일 이름 만 가져 오는 방법?

그냥 그 디렉토리에서 하나의 파일 이름을 원합니다; 명령은 중요하지 않습니다.

파일이 처리되고 삭제됩니다.

이것은 스크립트 작업 디렉토리가 아닙니다.

의도는 다음과 같습니다

  • 해당 파일을 열려면
  • 이 그것을 읽고,
  • 물건을,
  • 는 연결을 해제 한 후 다음 파일로
  • 루프.

내 원래의 시도는 .txt 파일 만 검사하지 않으며 하나의 파일 이름에 대해서만 ~ 5000 개의 파일 이름을 모두 가져야합니다. 아마도 너무 많은 모듈을 호출 할 것입니까?

하위는 디렉토리가 있고 파일이 있음을 확인하기위한 것이지만 내 시도가 실패했습니다. 여기서는 도움을 요청하고 있습니다.

#!/usr/bin/perl -w 
use strict; 
use warnings; 
use CGI; 
use CGI ':standard'; 
print CGI::header(); 
use CGI::Carp qw(fatalsToBrowser warningsToBrowser); 
### 
use vars qw(@Files $TheFile $PathToFile); 
my $ListFolder = CGI::param('openthisfolder'); 
Get_File($ListFolder); 
### 
sub Get_File{ 
    $ListFolder = shift; 
    unless (Verify_Empty($ListFolder)) { 
    opendir(DIR,$ListFolder); 
    @Files = grep { $_ ne '.' && $_ ne '..' } readdir(DIR); 
    closedir(DIR); 
    foreach(@Files){ 
     $TheFile = $_; 
    } 
    #### This is where I go off to process and unlink file (sub not here) #### 
    $PathToFile = $ListFolder.'/'.$TheFile; 
    OpenFileReadPrepare($PathToFile); 
    #### After unlinked, the OpenFileReadPrepare sub loops back to this script. 
    } 
    else { 
    print qq~No more files to process~; 
    exit; 
    } 
    exit; 
} 
    #### 
sub Verify_Empty { 
    $ListFolder = shift; 
    opendir(DIR, $ListFolder) or die "Not a directory"; 
    return scalar(grep { $_ ne "." && $_ ne ".." } readdir(DIR)) == 0; 
    closedir(DIR); 
} 

분명히 나는이 점에서 매우 새롭다. 이 방법은 상당히 배가 고프다 고 생각하십니까? 하나의 파일 이름을 잡고 처리하는 데 많은 도움이됩니다. 안내가 잘 될 것입니다!

편집 -latest 시도

my $dir = '..'; 
my @files = glob "$dir/*.txt"; 
for (0..$#files){ 
$files[$_] =~ s/\.txt$//; 
} 
my $PathAndFile =$files[0].'.txt'; 
print qq~$PathAndFile~; 

이 "작품"하지만, 여전히 모든 파일 이름을 가져옵니다. 지금까지 아무런 예제도 없었습니다. 내가 알아낼 때까지 오늘 같이 살거야. 아마도 나는 누군가가 더 좋은 것을 생각해 냈는지 다시 생각해 볼 것이다.

+1

"처음"을 정의 하시겠습니까? 처음부터 끝까지 언급 할 때 순서가 중요하지 않다고 말하는 것은 매우 이상하게 들립니다. 이것은 모든 파일을 반복하고 싶다는 말의 아주 복잡한 방식일까요? – TLP

+0

'foreach (... $ TheFile ..)'와'foreach (@Files) {$ TheFile = $ _; '대신 foreach my $ TheFile (@Files) {'를 쓰는 것을 선호합니다. 변수에 가장 작은 범위를주고'$ _ '을 사용하지 않는 이점이 있습니다. – AdrianHHH

+0

'$ ListFolder'가 둘 다 범위 내에 있으므로'Get_File'과'Verify_Empty' 호출에 필요한 매개 변수는 필요 없습니다; 첫 번째 과제는 이미 변수에 이미 포함 된 값으로 덮어 씁니다. – AdrianHHH

답변

4

루프 내에서 readdir을 사용하여 루프 할 수 있습니다. 모든 파일을 반환하지만 시간에 하나를 제공하지 않습니다 그런 식으로가 readdir에서

# opendir(DIR, ...); 
my $first_file = ""; 
while (my $file = readdir(DIR)) { 

    next if $file eq "." or $file eq ".."; 
    $first_file = $file; 
    last; 
} 
print "$first_file\n"; # first file in directory 
+0

파일 이름을 반환 할 수 없습니다. 파일은 스크립트와 동일한 디렉토리에 있지 않지만 한 디렉토리 아래에 있습니다. – OldDogLearningNewPerlTricks

+1

@ Student33, 뭔가 잘못하고 있어요. 이 코드 스 니펫은 열어 놓은 디렉토리를 지정하지 않습니다. 또한 본질적으로 옳습니다. – pilcrow

+0

먼저 opendir해야합니다. my $ ListFolder = CGI :: param ('openthisfolder'); opendir (DIR, $ ListFolder); –

2

내가 크게 잘못 생각하지 않는 한, 당신이 원하는 것은 "디렉토리에있는 파일을 반복 다만, 모든이에 대한 첫 번째 또는 마지막 "및"순서는 중요하지 않습니다. "파일을 삭제하는 것은이 작업을 수행하는 방법과 혼동을줍니다. 내가 당신을 위해 매우 간단한 방법에 넣어, 그리고 실제로 당신이 원하는 않는 경우 보자

그래서, :

my $directory = "somedir"; 
for my $file (<$directory/*.txt>) { 
    # do stuff with the files 
} 

glob이 * nix 쉘과 동일 할 것입니다 것, 그것은 것 확장자가 .txt 인 파일을 나열하십시오. 루프 내부의 파일에 대한 추가 테스트를 수행하려는 경우에는 문제가 없습니다.

단점은 메모리에 5000 개의 파일 이름을 유지하는 것입니다. 또한이 파일 목록을 처리하는 데 시간이 걸리면이 파일에도 액세스하는 다른 프로세스와 충돌 할 가능성이 있습니다.

대안은 대답에서 언급 한 mpapec과 같이 while 루프에서 readdir으로 파일을 읽는 것입니다. 이점은 새로운 파일 이름을 읽을 때마다 파일이 존재한다는 것입니다. 또한 메모리에 많은 파일 목록을 보관할 필요가 없습니다.

+0

아니요, 모든 파일을 반복하고 싶지 않습니다. 그것이 내가 피하려고하는 것입니다. 나는 하나의 filename.txt만을 원한다. – OldDogLearningNewPerlTricks

+0

음, 임의의 파일을 원하십니까? 아니면? 첫 번째는 파일 이름이 정렬된다는 것을 의미하지만 orderr은 중요하지 않습니다. – TLP

+0

수정. 모든 파일 이름. 어느 것이 든 그것이 최소한의 자원을 사용한다는 것을 의미합니다. – OldDogLearningNewPerlTricks

4

목록 컨텍스트에서 readdir을 호출하면 모든 디렉토리 항목이 반환됩니다. 대신 스칼라 컨텍스트로 호출하십시오.

my $file; 
while(my $entry = readdir DIR) { 

    $file = $entry, last if $entry =~ /\.txt$/;   
} 

if (defined $file) { 
    print "found $file\n"; 
    # process.... 
} 

또한 디렉토리를 두 ​​번 읽습니다. 한 번 항목에 있는지 확인한 다음 처리해야합니다. 디렉토리가 비어 있는지 실제로 확인하지 않아도됩니다. 처리 루프 중에는 무료로 사용할 수 있습니다.

+0

나는 이것이 내가 찾고있는 것 이상이라고 생각한다. 지금 시도 중입니다 ... – OldDogLearningNewPerlTricks

+0

파일 이름을 반환 할 수 없습니다. 파일은 스크립트와 동일한 디렉토리에 있지 않지만 한 디렉토리 아래에 있습니다. 나는 아무 소용이 없도록 수정하려고 노력했다. – OldDogLearningNewPerlTricks

+0

@ Student33이 코드 스 니펫도 열 디렉토리를 지정하지 않으며 실질적으로 정확합니다. 당신은 그것을 적응 시키는데있어 잘못된 것을하고 있습니다. – pilcrow