12
votes

Comment répertorier tous les fichiers d'un répertoire à l'aide de Perl?

J'utilise habituellement quelque chose comme xxx

ou parfois j'utilise glob , mais de toute façon, j'ai toujours besoin d'ajouter une ligne ou deux pour filtrer . et .. qui est assez gênant. Comment allez-vous habituellement sur cette tâche commune?


2 commentaires

De l'explosion des réponses, vous pouvez voir qu'il dépend entièrement de ce que vous voulez obtenir. :)


Duplicatural possible de Comment faire J'ai lu dans le contenu d'un répertoire à Perl? .


6 Réponses :


14
votes
my @files = grep {!/^\./} readdir DIR;
This will exclude all the dotfiles as well, but that's usually What You Want.

0 commentaires

7
votes

Si certains des dotfiles sont importants,

my @files = grep !/^\.\.?$/, readdir DIR;


1 commentaires

Eh bien, cela pourrait exclure ".. \ n", qui est légal à UNIX. Pas que je souhaite que le nom de famille sur qui que ce soit, mais les gens font des choses étranges à voir si une personne ignorera un fichier à laquelle ils se trouvaient dans votre répertoire. Vous pouvez résoudre ce problème avec un \ z au lieu de $ :)



7
votes

Je vais normalement utiliser la méthode globe code>: xxx pré>

ceci fonctionne correctement, à moins que le répertoire ait beaucoup de fichiers. Dans ces cas, vous devez revenir à readdir code> dans un pendant code> boucle (mettre lisdier code> dans la liste contextuelle est tout aussi mauvais que le GLOB CODE>): P>

use File::Find;

find sub {
    return if /^[.]/;
    #do stuff with $_ or $File::Find::name
}, $dir;


2 commentaires

L'utilisation de [.] est très curieuse --- Pourquoi préférez-vous que \. ?


@Chris Jester-Young, je l'aime mieux. Il semble moins bruyant (voir Syndrome de cure-dents penché ). En outre, et cela fait rationaliser, des échappées dans Regex ont tendance à signifier "le caractère suivant fait quelque chose de spécial" (par exemple, \ x {2e} ), mais \. signifie qu'il est juste une période. Étant donné que la plupart des personnages n'ont pas de sens particulière dans une classe de personnages, cela fait un bon mécanisme d'évacuation.



3
votes

Lorsque je veux juste que je veux juste que les fichiers (par opposition aux répertoires), j'utilise grep code> avec un -f test code> test:

my @files = grep { -f } readdir $dir;


2 commentaires

Cela ne fonctionnera que si le répertoire gérer est destiné au répertoire actuel.


@Chris: Bon point, il faudrait d'abord chDir, ou construire un nom de chemin absolu dans le Grep avec Fichier :: Spec-> Catfile ($ DirName, $ _) .



9
votes

J'utilise souvent fichier :: slurp . Les avantages comprennent: (1) meurt automatiquement si le répertoire n'existe pas. (2) exclut . Code> et .. code> par défaut. C'est ce que le comportement est comme readdir code> dans lequel elle ne renvoie pas les chemins complets.

use File::Util;
my $dir = '/path/to/dir';
my $fu = File::Util->new;
my @contents = $fu->list_dir( $dir, '--with-paths', '--no-fsdots' );


3 commentaires

... ce n'était pas une exigence de l'OP. Il ne voulait que filtrer . et .. .


Joli. Puis-je le faire renvoyer les chemins complets (pas les babots)?


@David B Vous pouvez également envisager fichier :: util , comme indiqué dans la réponse modifiée.



0
votes

Merci Chris et éther pour vos recommandations. J'ai utilisé ce qui suit pour lire une liste de tous les fichiers (annuaires exclus), à partir d'une poignée de répertoire faisant référence à un répertoire autre que mon répertoire actuel, dans une matrice. Le tableau a toujours manqué un fichier lorsque vous n'utilisez pas le chemin absolu de l'instruction GREP

use File::Slurp; 

print "\nWhich folder do you want to replace text? " ;
chomp (my $input = <>);
if ($input eq "") {
print "\nNo folder entered exiting program!!!\n";
exit 0;
} 

opendir(my $dh, $input) or die "\nUnable to access directory $input!!!\n"; 

my @dir = grep { -f "$input\\$_" } readdir $dh;


0 commentaires