2009-10-02 4 views
9

J'utilise ce code pour obtenir une liste de tous les fichiers dans un répertoire spécifique:Comment puis-je obtenir une liste de tous les fichiers avec une certaine extension d'un répertoire spécifique?

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

Comment puis-je modifier ce code ou d'ajouter quelque chose à afin qu'il ne recherche que les fichiers texte et charge uniquement le tableau avec le préfixe du nom de fichier?

contenu du répertoire Exemple:

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

Exemple contenu du tableau:

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

Pensez aussi à utiliser une variable lexicale pour votre répertoire: 'opendir mon $ dirh, $ dir_path ou die" ne peut pas ouvrir dir dir: $! ";' –

Répondre

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

une idée de comment regex le répertoire aussi? ma sortie est/dir/dir/dir/923847 ... comment puis-je obtenir le 923847? – CheeseConQueso

+0

glob ajoute un travail supplémentaire ici. Voir http://stackoverflow.com/questions/1506801/what-reasons-are-there-to-prefer-glob-over-readdir-or-vice-versa-in-perl –

5

il suffit de changer une ligne:

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

Pour Parvenez ». fichiers txt ", vous pouvez utiliser un test de fichier oper ator (-f: fichier normal) et une regex.

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

Sinon, vous pouvez chercher seulement des fichiers texte, en utilisant -T de Perl (opérateur de test de fichier ascii-texte)

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

-T est pour tester si vous avez un "textfile" – reinierpost

+0

Bon point; de la page perldoc sur l'opérateur (http://perldoc.perl.org/5.8.8/perlfunc.html), "-T \t Le fichier est un fichier texte ASCII (supposition heuristique)." s'il cherche des fichiers ".txt", cela fera exactement ce qu'il demande sans deviner. –

3

Si vous pouvez utiliser les nouvelles fonctionnalités de Perl 5.10, voici comment Je l'écrirais.

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 
} 

Ou si vous avez des répertoires très grand, vous pouvez utiliser une boucle while.

{ 
    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

Il suffit d'utiliser ceci:

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

C'est la façon la plus simple que j'ai trouvé (comme lisible par l'homme) en utilisant la fonction 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"; 
} 

De plus, le « -f "garantit que seuls les fichiers réels (et non les répertoires) sont stockés dans le tableau.

+0

Pourquoi annuler l'édition? 'foreach $ file' n'est pas un coffre-fort strict. Si vous préférez 'foreach' à' for', pourquoi pas 'foreach my $ file'? –

+0

Pourquoi éditer quelqu'un de vieux trucs quand vous ne savez pas pourquoi il a été posté en premier lieu? Je ne sais même pas la raison pour laquelle j'ai écrit ce code il y a plus de trois ans, mais comme j'ai l'habitude de tester quelque chose, ça a probablement très bien fonctionné, et il y a probablement une raison pour laquelle je n'ai pas ajouté déclaration soit. Cela signifie-t-il que je devrais accepter une modification aléatoire et que je veux même passer du temps à la tester? Sûrement pas!C'est pourquoi je l'ai trouvé beaucoup plus sûr de le faire rouler en arrière. – Kebman

+0

Juste pour être clair, ce n'est pas moi qui l'ai édité, j'ai juste vu le montage et j'ai pensé qu'il améliorait la réponse. C'est juste bizarre que vous utilisiez un 'fichier 'lexical puis un' $ file' global. –

Questions connexes