سؤال

كيف أجعل 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;

أولاً، لتوثيق ما يفعله لأن الملصق لم يفعل:إنه يمرر القائمة المرتجعة من قراءة دير () من خلال أ جريب () يُرجع فقط تلك القيم التي تكون عبارة عن ملفات (على عكس الدلائل، والأجهزة، والأنابيب المسماة، وما إلى ذلك) والتي لا تبدأ بنقطة (مما يجعل اسم القائمة @dots مضللة، ولكن هذا بسبب التغيير الذي أجراه عند نسخه من وثائق readdir()).نظرًا لأنه يحد من محتويات الدليل الذي يعيده، لا أعتقد أنه إجابة صحيحة من الناحية الفنية لهذا السؤال، ولكنه يوضح لغة شائعة تستخدم لتصفية أسماء الملفات في بيرل, ، واعتقدت أنه سيكون من المفيد توثيقه.مثال آخر رأيناه كثيرًا هو:

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

يقرأ هذا المقتطف جميع المحتويات من مقبض الدليل D يستثني ''. " و '..' ، لأن هذه نادرا ما تكون مطلوبة لاستخدامها في القائمة.

نصائح أخرى

الحل السريع والقذر هو الاستخدام الكرة الأرضية

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

ايو::دير جميل ويوفر واجهة تجزئة مرتبطة أيضًا.

من بيرلدوك:

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