如何在Perl中读取目录的内容?

时间:2020-03-05 18:42:04  来源:igfitidea点击:

我如何让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";
}

EDIT2:大多数其他答案都是有效的,但我想对此提供具体解决方案的评论:

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

首先,要记录自发布者以来没有做的事情:它通过grep()从readdir()返回的列表传递给grep(),后者仅返回文件(与目录,设备,命名管道等相反)的值。并且不要以点开头(这会使列表名称" @dots"产生误导,但这是由于他从readdir()文档复制过来时所做的更改)。由于它限制了返回目录的内容,因此从技术上讲,我认为这不是一个正确的答案,但是它说明了用于过滤Perl中文件名的常见用法,我认为这对记录很有用。另一个例子很多:

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

此代码段从目录句柄D中读取除"。"以外的所有内容。和" ..",因为很少希望在清单中使用它们。

回答

只需一行即可完成操作(请注意最后的" *"通配符)

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

回答

这是一个通过目录结构递归并从我编写的备份脚本中复制文件的示例。

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";       
}

回答

IO :: Dir很不错,并且还提供了一个绑定的哈希接口。

从perldoc:

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;

回答

一种快速而肮脏的解决方案是使用glob

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

回答

与上述类似,但我认为最好的版本是(略作修改)来自" perldoc -f readdir":

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

回答

我们可以使用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()函数提供了一种更简洁的接口。