2008-08-22 8 views

Respuesta

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

EDIT: Ah, lo siento, se perdió el "en una matriz" parte:

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 mayoría de las otras respuestas son válidas, pero quería hacer comentarios sobre this answer específicamente, en el cual esta solución se ofrece:

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

en primer lugar, para documentar lo que está haciendo ya que el cartel no lo hizo: se pasa a la lista de regresar de readdir() a través de un grep() t solo devuelve aquellos valores que son archivos (a diferencia de directorios, dispositivos, canalizaciones con nombre, etc.) y que no comienzan con un punto (lo que hace que el nombre de la lista @dots sea engañoso, pero eso se debe al cambio que realizó al copiarlo más de la documentación readdir()). Como limita el contenido del directorio que devuelve, no creo que técnicamente sea una respuesta correcta a esta pregunta, pero ilustra una expresión común utilizada para filtrar nombres de archivo en Perl, y pensé que sería valioso documentar. Otro ejemplo se ve mucho es:

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

Este fragmento se lee todo el contenido de la manija directorio D excepto ''. y '..', ya que rara vez se desea utilizarlos en la lista.

6

Esto lo hará, en una línea (nótese el '*' comodín al final)

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

¿Puede alguien explicarme por qué esto es "incorrecto"? Porque es limpio y simple (a diferencia de otras soluciones), pero se ha modificado sin explicación. – rix0rrr

+0

Apenas recuerdo haber leído que el globbing depende del caparazón utilizado, quizás sea por eso. – maaartinus

+0

Esta es la mejor solución, está limpia y funcionó perfectamente para mí. – mikemeli

1

He aquí un ejemplo de manera recursiva a través de una escritura de reserva froma estructura de directorios y archivos de copia escribí.

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 es agradable y proporciona una interfaz de hash atado así.

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

Por lo que podría hacer algo como:

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

Una solución rápida y sucia es utilizar glob

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

, vale la pena señalar que 'glob' no funciona como se esperaba con espacios en la ruta en windows- http://stackoverflow.com/questions/7898496/can-not-list-directory-including-space-using-perl-in -windows-platform – Kip

+0

a veces las soluciones sucias funcionan bien. – serenesat

+0

Esto tampoco encontrará los archivos ocultos (aquellos que comienzan con un punto). – josch

1

similar a la anterior, pero creo que la mejor versión (ligeramente modificada) de "perldoc -f readdir":

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

Usted podría utilizar 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 proporciona una alternativa, la interfaz más limpia a los opendir(), closedir(), readdir() y rewinddir() funciones.

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

El siguiente ejemplo (en base a un ejemplo de código de readdir perldoc f) se lleva todos los archivos (no directorios) que comienzan con un periodo desde el directorio abierto. Los nombres de archivo se encuentran en la matriz @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; 
Cuestiones relacionadas