2009-06-11 13 views
7

Ho bisogno di cercare i file in una directory che inizia con un modello particolare, diciamo "abc". Devo anche eliminare tutti i file nel risultato che terminano con ".xh". Non sono sicuro di come farlo nel Perl.Filtro nomi file per modello

ho qualcosa di simile a questo:

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

Ho anche bisogno di eliminare tutti i file dal risultato che terminano con ".xh"

Grazie, Bi

risposta

7

provare

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

dove MYDIR è una stringa contenente il percorso della directory.

+0

è necessario ancorare l'espressione regolare alla fine della stringa e sfuggire a. in qualche modo (mi piace usare una classe di caratteri). Poiché è la tua regex corrisponderà a "abcxh.txt". Prova invece a /[.]xh$/. –

+0

Grazie - ha funzionato! –

+0

Dispari, ho avuto un sacco di problemi nel far sì che questa risposta si formatta correttamente: ho evitato il periodo, ma non mostra (a meno che non fugga dalla fuga). Anche lo < e lo > sono stati una lotta! Grazie per aver catturato l'ancora $, non ho provato per quel caso. Risolto. –

-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. 
      } 
    } 
} 

anche, tutto i file in una directory sono accessibili facendo:

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

In alternativa è possibile utilizzare il modulo perl File :: find.

7

opendir (MYDIR, $ newpath); my @files = grep (/ abc *. * /, readdir (MYDIR)); # NON FUNZIONA

Si confonde un motivo regolare con un motivo 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

Il punto che kevinadc e Sinan Unur stanno usando, ma non nota è che readdir() restituisce un elenco di tutte le voci della rubrica quando viene chiamato in contesto di lista. È quindi possibile utilizzare qualsiasi operatore di elenco su questo. Ecco perché si può usare:

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

Quindi:

readdir MYDIR 

restituisce un elenco di tutti i file in MYDIR.

E:

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

restituisce tutti gli elementi restituiti dalla readdir MYDIR che corrispondono ai criteri di lì.

+0

Modifica che il secondo controllo sia /.xh$/ e controllerai la cosa giusta. :) –

-1

Invece di usare opendir e filtraggio readdir (non dimenticate di closedir!), Si potrebbe invece utilizzare 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) 

Se non si cura di eliminare il prefisso $newpath ai risultati di glob , sbarazzarsi del map+splitpath.

+0

Non c'è bisogno della mappa o dello splitpath. O finisce in .xh o no. Il lavoro extra non lo cambia. –

+0

Eh? glob ("./ abc *") restituisce ("./abc.txt", "./abc.xh"); in quale altro modo ti aspetti di ridurlo a ("abc.txt")? – ephemient

Problemi correlati