문제

Perl이 주어진 디렉토리의 내용을 배열로 읽도록 하려면 어떻게 해야 합니까?

백틱 할 수 있는데, 'scandir'이나 비슷한 용어를 사용하는 방법이 있나요?

도움이 되었습니까?

해결책

opendir(D, "/path/to/directory") || die "Can't open directory: $!\n";
while (my $f = readdir(D)) {
    print "\$f = $f\n";
}
closedir(D);

편집하다:아, 죄송합니다. "배열 속으로" 부분을 놓쳤습니다.

my $d = shift;

opendir(D, "$d") || die "Can't open directory $d: $!\n";
my @list = readdir(D);
closedir(D);

foreach my $f (@list) {
    print "\$f = $f\n";
}

편집2:다른 답변의 대부분은 유효하지만 이에 대해 언급하고 싶었습니다. 이 답변 특히 이 솔루션은 다음과 같이 제공됩니다.

opendir(DIR, $somedir) || die "Can't open directory $somedir: $!";
@dots = grep { (!/^\./) && -f "$somedir/$_" } readdir(DIR);
closedir DIR;

먼저, 포스터가 다음을 수행하지 않았기 때문에 수행 중인 작업을 문서화하려면 다음을 수행하십시오.반환된 목록을 다음에서 전달하고 있습니다. readdir() 통해 그렙() 이는 파일(디렉토리, 장치, 명명된 파이프 등과 반대)이고 점으로 시작하지 않는 값(목록 이름을 만듭니다.)만 반환합니다. @dots 오해의 소지가 있지만 이는 그가 readdir() 문서에서 복사할 때 변경한 사항 때문입니다.반환되는 디렉터리의 내용을 제한하기 때문에 기술적으로 이 질문에 대한 정답은 아니지만 파일 이름을 필터링하는 데 사용되는 일반적인 관용어를 보여줍니다. , 그리고 문서화하는 것이 가치가 있다고 생각했습니다.많이 볼 수 있는 또 다른 예는 다음과 같습니다.

@list = grep !/^\.\.?$/, readdir(D);

이 조각은 디렉터리 핸들 D의 모든 내용을 읽습니다. 제외하고 '.' 그리고 '..', 이들은 목록에 사용하기를 거의 원하지 않기 때문입니다.

다른 팁

빠르고 더러운 해결책은 다음을 사용하는 것입니다. 글로브

@files = glob ('/path/to/dir/*');

IO::디렉토리 훌륭하고 묶인 해시 인터페이스도 제공합니다.

펄독에서:

use IO::Dir;
$d = IO::Dir->new(".");
if (defined $d) {
    while (defined($_ = $d->read)) { something($_); }
    $d->rewind;
    while (defined($_ = $d->read)) { something_else($_); }
    undef $d;
}

tie %dir, 'IO::Dir', ".";
foreach (keys %dir) {
    print $_, " " , $dir{$_}->size,"\n";
}

따라서 다음과 같이 할 수 있습니다.

tie %dir, 'IO::Dir', $directory_name;
my @dirs = keys %dir;

이렇게 하면 한 줄에 완료됩니다(끝 부분에 '*' 와일드카드가 있음).

@files = </path/to/directory/*>;
# To demonstrate:
print join(", ", @files);

당신은 사용할 수 있습니다 DirHandle:

use DirHandle;
$d = new DirHandle ".";
if (defined $d)
{
    while (defined($_ = $d->read)) { something($_); }
    $d->rewind;
    while (defined($_ = $d->read)) { something_else($_); }
    undef $d;
}

DirHandle 대체적이고 깔끔한 인터페이스를 제공합니다. opendir(), closedir(), readdir(), 그리고 rewinddir() 기능.

다음은 디렉터리 구조를 반복하고 내가 작성한 백업 스크립트에서 파일을 복사하는 예입니다.

sub copy_directory {
my ($source, $dest) = @_;
my $start = time;

# get the contents of the directory.
opendir(D, $source);
my @f = readdir(D);
closedir(D);

# recurse through the directory structure and copy files.
foreach my $file (@f) {
    # Setup the full path to the source and dest files.
    my $filename = $source . "\\" . $file;
    my $destfile = $dest . "\\" . $file;

    # get the file info for the 2 files.
    my $sourceInfo = stat( $filename );
    my $destInfo = stat( $destfile );

    # make sure the destinatin directory exists.
    mkdir( $dest, 0777 );

    if ($file eq '.' || $file eq '..') {
    } elsif (-d $filename) { # if it's a directory then recurse into it.
        #print "entering $filename\n";
        copy_directory($filename, $destfile); 
    } else { 
        # Only backup the file if it has been created/modified since the last backup 
        if( (not -e $destfile) || ($sourceInfo->mtime > $destInfo->mtime ) ) {
            #print $filename . " -> " . $destfile . "\n";
            copy( $filename, $destfile ) or print "Error copying $filename: $!\n";
        } 
    } 
}

print "$source copied in " . (time - $start) . " seconds.\n";       
}

위와 유사하지만 가장 좋은 버전은 "perldoc -f readdir"의 버전입니다(약간 수정됨).

opendir(DIR, $somedir) || die "can't opendir $somedir: $!";
@dots = grep { (!/^\./) && -f "$somedir/$_" } readdir(DIR);
closedir DIR;

에서: http://perlmeme.org/faqs/file_io/directory_listing.html

#!/usr/bin/perl
use strict;
use warnings;

my $directory = '/tmp';

opendir (DIR, $directory) or die $!;

while (my $file = readdir(DIR)) {
    next if ($file =~ m/^\./);
    print "$file\n";
}

다음 예(perldoc -f readdir의 코드 샘플을 기반으로 함)는 열린 디렉토리에서 마침표로 시작하는 모든 파일(디렉토리 아님)을 가져옵니다.파일 이름은 @dots 배열에 있습니다.

#!/usr/bin/perl

use strict;
use warnings;

my $dir = '/tmp';

opendir(DIR, $dir) or die $!;

my @dots 
    = grep { 
        /^\./             # Begins with a period
    && -f "$dir/$_"   # and is a file
} readdir(DIR);

# Loop through the array printing out the filenames
foreach my $file (@dots) {
    print "$file\n";
}

closedir(DIR);
exit 0;


closedir(DIR);
exit 0;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top