2009-06-11 12 views
7

J'ai besoin de rechercher des fichiers dans un répertoire qui commence par un motif particulier, disons "abc". J'ai aussi besoin d'éliminer tous les fichiers dans le résultat qui se terminent par ".xh". Je ne suis pas sûr de savoir comment le faire en Perl.Filtrer les noms de fichiers par motif

J'ai quelque chose comme ceci:

opendir(MYDIR, $newpath); 
my @files = grep(/abc\*.*/,readdir(MYDIR)); # DOES NOT WORK 

Je dois aussi d'éliminer tous les fichiers de résultat qui se terminent par "xH"

Merci, Bi

Répondre

7

essayer

@files = grep {!/\.xh$/} <$MYDIR/abc*>; 

où MYDIR est une chaîne contenant le chemin de votre répertoire.

+0

vous devez ancrer cette regex à la fin de la chaîne et échapper le. en quelque sorte (j'aime utiliser une classe de caractères). Comme c'est votre regex correspondra "abcxh.txt". Essayez /[.]xh$/ à la place. –

+0

Merci - cela a fonctionné! –

+0

Bizarre, j'ai eu beaucoup de problèmes pour obtenir cette réponse au format correct - j'ai échappé à la période, mais ça ne se voit pas (à moins que j'échappe à l'évasion). Aussi le <et> étaient un combat! Merci d'avoir attrapé l'ancre $, je n'ai pas testé pour ce cas. Fixé. –

-1
foreach $file (@files) 
{ 
    my $fileN = $1 if $file =~ /([^\/]+)$/; 

    if ($fileN =~ /\.xh$/) 
    { 
      unlink $file; 
      next; 
    } 
    if ($fileN =~ /^abc/) 
    { 
      open(FILE, "<$file"); 
      while(<FILE>) 
      { 
      # read through file. 
      } 
    } 
} 

aussi, tous les les fichiers dans un répertoire sont accessibles en faisant:

$DIR = "/somedir/somepath"; 
foreach $file (<$DIR/*>) 
{ 
    # apply file checks here like above. 
} 

ALternativement, vous pouvez utiliser le module perl File :: find.

7

opendir (MYDIR, $ newpath); mon @files = grep (/ abc *. * /, readdir (MYDIR)); #DOES NOT WORK

Vous confondez un motif regex avec un motif glob.

#!/usr/bin/perl 

use strict; 
use warnings; 

opendir my $dir_h, '.' 
    or die "Cannot open directory: $!"; 

my @files = grep { /abc/ and not /\.xh$/ } readdir $dir_h; 

closedir $dir_h; 

print "$_\n" for @files; 
3
opendir(MYDIR, $newpath) or die "$!"; 
my @files = grep{ !/\.xh$/ && /abc/ } readdir(MYDIR); 
close MYDIR; 
foreach (@files) { 
    do something 
} 
2

Le point kevinadc et Sinan Unur utilisent, mais pas de mentionner que readdir() renvoie une liste de toutes les entrées dans le répertoire lorsque appelé dans un contexte de liste. Vous pouvez ensuite utiliser n'importe quel opérateur de liste sur cela. Voilà pourquoi vous pouvez utiliser:

my @files = grep (/abc/ && !/\.xh$/), readdir MYDIR; 

Alors:

readdir MYDIR 

retourne une liste de tous les fichiers MYDIR.

Et:

grep (/abc/ && !/\.xh$/) 

renvoie tous les éléments retournés par readdir MYDIR qui correspondent aux critères là.

+0

Modifiez cette deuxième vérification pour qu'elle soit /\.xh$/ et vous vérifierez la bonne chose. :) –

-1

Au lieu d'utiliser opendir et le filtrage readdir (ne pas oublier de closedir!), Vous pouvez utiliser à la place glob:

use File::Spec::Functions qw(catfile splitpath); 

my @files = 
    grep !/^\.xh$/,    # filter out names ending in ".xh" 
    map +(splitpath $_)[-1],  # filename only 
    glob       # perform shell-like glob expansion 
     catfile $newpath, 'abc*'; # "$newpath/abc*" (or \ or :, depending on OS) 

Si vous ne se soucient pas de l'élimination de la $newpath préfixé aux résultats de glob , se débarrasser de la map+splitpath.

+0

Vous n'avez pas besoin de la carte ou du splitpath. Soit il se termine par .xh ou pas. Le travail supplémentaire ne change pas cela. –

+0

Huh? glob ("./ abc *") renvoie ("./abc.txt", "./abc.xh"); Sinon, comment espérez-vous le faire tourner vers ("abc.txt")? – ephemient