2009-10-02 17 views
9

używam tego kodu, aby uzyskać listę wszystkich plików w określonym katalogu:Jak mogę uzyskać listę wszystkich plików o określonym rozszerzeniu z określonego katalogu?

opendir DIR, $dir or die "cannot open dir $dir: $!"; 
my @files= readdir DIR; 
closedir DIR; 

Jak można zmodyfikować ten kod lub dodać coś do niego tak, że wygląda tylko dla plików tekstowych i tylko obciążeń tablica z przedrostkiem nazwy pliku?

zawartość Przykład katalogu: zawartość tablicy

. 
.. 
923847.txt 
98398523.txt 
198.txt 
deisi.jpg 
oisoifs.gif 
lksdjl.exe 

Przykład:

files[0]=923847 
files[1]=98398523 
files[2]=198 
+0

Należy również rozważyć użycie zmiennej leksykalnej dla uchwytu katalogu: 'opendir my $ dirh, $ dir_path or die" nie można otworzyć dir $ dir: $! ";' –

Odpowiedz

10
my @files = glob "$dir/*.txt"; 
for (0..$#files){ 
    $files[$_] =~ s/\.txt$//; 
} 
+0

żadnego pomysłu jak również wyreperować katalog? moje wyjście to/dir/dir/dir/923847 ... jak mogę dostać 923847? – CheeseConQueso

+0

glob dodaje dodatkową pracę tutaj. Zobacz http://stackoverflow.com/questions/1506801/what-reasons-are-there-to-prefer-glob-over-readdir-or-vice-versa-in-perl –

5

wystarczy zmienić jedną linię:

my @files= map{s/\.[^.]+$//;$_}grep {/\.txt$/} readdir DIR; 
2

Aby uzyskać tylko”. txt ", możesz użyć pliku testowego ator (-f: zwykły plik) i regex.

my @files = grep { -f && /\.txt$/ } readdir $dir; 

W przeciwnym razie, można szukać tylko plików tekstowych przy użyciu Perl (operator testowy plik ASCII-text) -T

my @files = grep { -T } readdir $dir; 
+0

-T jest do testowania, czy masz "textfile" – reinierpost

+0

Dobra rada; ze strony perldoc na operatorze (http://perldoc.perl.org/5.8.8/perlfunc.html), "-T \t Plik jest plikiem tekstowym ASCII (przypuszczenie heurystyczne)." jeśli szuka plików ".txt", zrobi dokładnie to, o co prosi bez zgadywania. –

3

Jeśli można użyć nowych funkcji Perl 5.10, to w jaki sposób Napisałbym to.

use strict; 
use warnings; 
use 5.10.1; 
use autodie; # don't need to check the output of opendir now 

my $dir = "."; 

{ 
    opendir my($dirhandle), $dir; 
    for(readdir $dirhandle){ # sets $_ 
    when(-d $_){ next } # skip directories 
    when(/^[.]/){ next } # skip dot-files 

    when(/(.+)[.]txt$/){ say "text file: ", $1 } 
    default{ 
     say "other file: ", $_; 
    } 
    } 
    # $dirhandle is automatically closed here 
} 

Lub jeśli masz bardzo dużych katalogów, można użyć while pętlę.

{ 
    opendir my($dirhandle), $dir; 
    while(my $elem = readdir $dirhandle){ 
    given($elem){ # sets $_ 
     when(-d $_){ next } # skip directories 
     when(/^[.]/){ next } # skip dot-files 

     when(/(.+)[.]txt$/){ say "text file: ", $1 } 
     default{ 
     say "other file: ", $_; 
     } 
    } 
    } 
} 
1

Wystarczy użyć tego:

my @files = map {-f && s{\.txt\z}{} ? $_ :()} readdir DIR; 
1

Jest to najprostszy sposób znalazłem (jak w czytelny dla człowieka) przy użyciu funkcji glob:

# Store only TXT-files in the @files array using glob 
my @files = grep (-f ,<*.txt>); 
# Write them out 
foreach $file (@files) { 
    print "$file\n"; 
} 

dodatkowo „-f "zapewnia, że ​​tylko rzeczywiste pliki (a nie katalogi) są przechowywane w tablicy.

+0

Dlaczego wycofać zmiany? 'foreach $ file' nie jest ściśle bezpieczny. Jeśli wolisz 'foreach' na' for', dlaczego nie 'foreach my $ file'? –

+0

Po co edytować kogoś, kto jest stary, skoro nie znasz przyczyny, dla której został on wysłany? Do diabła, nawet nie znam powodu, dla którego napisałem ten fragment kodu ponad trzy lata temu, ale ponieważ mam zwyczaj testowania rzeczy, prawdopodobnie działało dobrze, i prawdopodobnie istnieje powód, którego nie dodałem w ścisłym deklaracja. Czy to jednak oznacza, że ​​powinienem zaakceptować losową edycję i czy chcę nawet poświęcić czas na jej przetestowanie? Do diabła, nie!Dlatego właśnie odrzuciłem go znacznie bezpieczniej. – Kebman

+0

Dla jasności, to nie ja to redagowałem, właśnie zobaczyłem edycję i pomyślałem, że to poprawiło odpowiedź. To dziwne, że używasz leksykalnego '@ files', a następnie globalnego' $ file'. –

Powiązane problemy