Comment obtenir que Perl lise le contenu d'un répertoire donné dans un tableau?Comment lire le contenu d'un répertoire en Perl?
Backticks peut le faire, mais existe-t-il une méthode utilisant 'scandir' ou un terme similaire?
Comment obtenir que Perl lise le contenu d'un répertoire donné dans un tableau?Comment lire le contenu d'un répertoire en Perl?
Backticks peut le faire, mais existe-t-il une méthode utilisant 'scandir' ou un terme similaire?
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.
Cela fera, dans une ligne (notez le « * » générique à la fin)
@files = </path/to/directory/*>;
# To demonstrate:
print join(", ", @files);
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";
}
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;
Une solution rapide et sale est d'utiliser glob
@files = glob ('/path/to/dir/*');
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
parfois des solutions sales fonctionnent bien. – serenesat
Ceci ne trouvera pas non plus les fichiers cachés (ceux commençant par un point). – josch
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;
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.
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;
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
Je me souviens à peine d'avoir lu que la globalisation dépend de la coque utilisée, c'est peut-être pourquoi. – maaartinus
C'est la meilleure solution, c'est propre et cela a fonctionné parfaitement pour moi. – mikemeli