2008-10-15 10 views
16

J'essaie de traverser tous les sous-répertoires du répertoire courant en Perl, et d'obtenir des données à partir de ces fichiers. J'utilise grep pour obtenir une liste de tous les fichiers et dossiers dans le répertoire donné, mais je ne sais pas laquelle des valeurs retournées est un nom de dossier et qui est un fichier sans extension de fichier.Comment distinguer un fichier d'un répertoire en Perl?

Comment puis-je faire la différence?

Répondre

27

Vous pouvez utiliser un opérateur de test de fichier -d pour vérifier si quelque chose est un répertoire. Voici quelques-uns des opérateurs de test de fichiers généralement utiles

 
    -e File exists. 
    -z File has zero size (is empty). 
    -s File has nonzero size (returns size in bytes). 
    -f File is a plain file. 
    -d File is a directory. 
    -l File is a symbolic link. 

Voir perlfunc manual page for more

Aussi, essayez d'utiliser File::Find qui peut récursif des répertoires pour vous. Voici un exemple qui cherche des répertoires ....

sub wanted { 
    if (-d) { 
     print $File::Find::name." is a directory\n"; 
    } 
} 

find(\&wanted, $mydir); 
20
print "$file is a directory\n" if (-d $file); 
+0

Cela a fonctionné à merveille, grâce –

+1

La documentation pour toutes les fonctions de test de fichier peut être trouvé avec « perldoc -f -X » (ce qui est assez inintéressant, je l'admets). –

4
 
my $dh = opendir("."); 
my @entries = grep !/^\.\.?$/, readdir($dh); 
closedir $dh; 

foreach my $entry (@entries) { 
    if(-f $entry) { 
     # $entry is a file 
    } elsif (-d $entry) { 
     # $entry is a directory 
    } 
} 
2

Il serait plus facile d'utiliser File::Find.

9

Regardez les opérateurs -X:

perldoc -f -X 

Pour directory traversal, utilisez Fichier :: Rechercher, ou, si vous n'êtes pas masochiste, utilisez mon fichier :: Module suivant qui fait un itérateur pour vous et ne nécessite pas de rappels fous. En fait, vous pouvez avoir File :: Next ONLY retourner les fichiers, et ignorer les répertoires.

use File::Next; 

my $iterator = File::Next::files('/tmp'); 

while (defined (my $file = $iterator->())) { 
    print $file, "\n"; 
} 

# Prints... 
/tmp/foo.txt 
/tmp/bar.pl 
/tmp/baz/1 
/tmp/baz/2.txt 
/tmp/baz/wango/tango/purple.txt 

Il est à http://metacpan.org/pod/File::Next

5
my @files = grep { -f } @all; 
my @dirs = grep { -d } @all;