2008-08-22 6 views

Répondre

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

EDIT: Oh, désolé, a manqué le "dans un tableau" partie:

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: La plupart des autres réponses sont valables, mais je voulais commenter this answer spécifiquement, dans lequel cette solution est proposée:

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

Tout d'abord, pour documenter ce qu'il fait depuis l'affiche n'a pas: il est passe la liste retournée de readdir() par un grep() t hat ne renvoie que les valeurs qui sont des fichiers (par opposition aux répertoires, périphériques, pipes nommés, etc.) et qui ne commencent pas par un point (ce qui rend le nom de la liste trompeur, mais cela est dû au changement qu'il a fait lors de la copie plus de la documentation readdir()). Comme il limite le contenu du répertoire qu'il renvoie, je ne pense pas que ce soit techniquement une réponse correcte à cette question, mais il illustre un idiome commun utilisé pour filtrer les noms de fichiers dans Perl, et j'ai pensé qu'il serait utile de documenter. Un autre exemple vu beaucoup est:

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

Cet extrait se lit tout le contenu de la poignée de répertoire D sauf « » et '..', puisque ceux-ci sont très rarement désirés d'être utilisés dans la liste.

6

Cela fera, dans une ligne (notez le « * » générique à la fin)

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

Quelqu'un peut-il m'expliquer pourquoi c'est "faux"? Parce que c'est propre et simple (contrairement à d'autres solutions), mais il a été démodulé sans explication. – rix0rrr

+0

Je me souviens à peine d'avoir lu que la globalisation dépend de la coque utilisée, c'est peut-être pourquoi. – maaartinus

+0

C'est la meilleure solution, c'est propre et cela a fonctionné parfaitement pour moi. – mikemeli

1

Voici un exemple de récursion dans une structure de répertoires et copie de fichiers script de sauvegarde froma je l'ai écrit.

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

IO::Dir est agréable et offre une interface de hachage liée aussi bien.

De l'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"; 
} 

Ainsi, vous pouvez faire quelque chose comme:

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

Une solution rapide et sale est d'utiliser glob

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

vaut la peine de noter que «glob» ne fonctionne pas comme prévu avec des espaces dans le chemin sur windows- http://stackoverflow.com/questions/7898496/can-not-list-directory-including-space-using-perl-in -windows-platform – Kip

+0

parfois des solutions sales fonctionnent bien. – serenesat

+0

Ceci ne trouvera pas non plus les fichiers cachés (ceux commençant par un point). – josch

1

Comme ci-dessus, mais je pense que la meilleure version est (légèrement modifiée) de "perldoc -f readdir":

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

Vous pouvez utiliser 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 fournit une alternative, une interface plus propre aux opendir(), closedir(), readdir() et rewinddir() fonctions.

0

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

L'exemple suivant (basé sur un exemple de code à partir du readdir de perldoc) obtient tous les fichiers (pas les répertoires) en commençant par une période allant du répertoire ouvert. Les noms de fichiers se trouvent dans le tableau @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; 
Questions connexes