2009-06-25 16 views

Odpowiedz

65

Jeśli chcesz uzyskać zawartości danego katalogu, a tylko ona (tj żadnych podkatalogów), najlepszym sposobem jest użycie opendir/readdir/closedir:

opendir my $dir, "/some/path" or die "Cannot open directory: $!"; 
my @files = readdir $dir; 
closedir $dir; 

Można również użyć:

my @files = glob($dir . '/*'); 

Ale moim zdaniem to nie jest tak dobry - głównie dlatego, że glob jest dość skomplikowana sprawa (można filtrować wyniki automatycznie) i używając go, aby wszystkie elementy katalogu wydaje się zbyt proste zadanie.

Z drugiej strony, jeśli chcesz poznać zawartość od wszystkich katalogów i podkatalogów, nie ma w zasadzie jeden roztwór standardowy:

use File::Find; 

my @content; 
find(\&wanted, '/some/path'); 
do_something_with(@content); 

exit; 

sub wanted { 
    push @content, $File::Find::name; 
    return; 
} 
+0

Zawsze zapominam, że readdir po prostu zwraca listę względnych nazw plików, a nie całą ścieżkę! –

+0

Dziękujemy za zniechęcanie do korzystania z funkcji globowania w tym zadaniu. Kolejną wadą korzystania z globowania jest to, że nie znajdzie ukrytych plików (zaczynających się kropką). – josch

9

to powinno zrobić.

my $dir = "bla/bla/upload"; 
opendir DIR,$dir; 
my @dir = readdir(DIR); 
close DIR; 
foreach(@dir){ 
    if (-f $dir . "/" . $_){ 
     print $_," : file\n"; 
    }elsif(-d $dir . "/" . $_){ 
     print $_," : folder\n"; 
    }else{ 
     print $_," : other\n"; 
    } 
} 
+1

Należy sprawdzić opendir niepowodzenia (opendir ... or die „Komunikat o błędzie : $! "). Poza tym czegoś brakuje? Co robi tutaj Win32 :: GUI :: DoEvents()? (Nie widzę niczego istotnego w pytaniu.) – Telemachus

+0

jest to najlepszy sposób, w jaki nie chcę lub nie chcę pamiętać regularnych wyrażeń na coś, co powinno być łatwe do zrobienia, użyję tego, aby utworzyć funkcję taką jak lista ($ dir ,"fa"); dla plików "d" dla katalogu, dziękuję za opublikowanie tego – Geomorillo

11

Albo File::Find

use File::Find; 
finddepth(\&wanted, '/some/path/to/dir'); 
sub wanted { print }; 

Będzie przechodzić przez podkatalogi, jeśli takie istnieją.

2

To będzie lista Wszystko (w tym katalogi sub) z katalogu określić, w kolejności i z atrybutami. Spędziłem wiele dni, szukając czegoś, co można by zrobić, a ja brałem udział w całej tej dyskusji i trochę mojej, i składałem razem. CIESZYĆ SIĘ!!

#!/usr/bin/perl -- 
print qq~Content-type: text/html\n\n~; 
print qq~<font face="arial" size="2">~; 

use File::Find; 

# find(\&wanted_tom, '/home/thomas/public_html'); # if you want just one website, uncomment this, and comment out the next line 
find(\&wanted_tom, '/home'); 
exit; 

sub wanted_tom { 
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat ($_); 
$mode = (stat($_))[2]; 
$mode = substr(sprintf("%03lo", $mode), -3); 

if (-d $File::Find::name) { 
print "<br><b>--DIR $File::Find::name --ATTR:$mode</b><br>"; 
} else { 
print "$File::Find::name --ATTR:$mode<br>"; 
} 
    return; 
} 
+3

Arghh, moje oczy! – javs

3

Jeżeli jesteś próżniak jak ja może chcesz użyć modułu File::Slurp. Funkcja read_dir wola czyta zawartość katalogu do tablicy, usuwa punkty, a jeśli potrzebna prefiks pliki wrócił z katalogu dla bezwzględnych ścieżek

my @paths = read_dir('/path/to/dir', prefix => 1) ; 
Powiązane problemy