2009-06-11 33 views
7

Necesito buscar archivos en un directorio que comience con un patrón particular, diga "abc". También necesito eliminar todos los archivos en el resultado que terminan con ".xh". No estoy seguro de cómo hacerlo en Perl.Filtrar nombres de archivos por patrón

tengo algo como esto:

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

También necesito para eliminar todos los archivos de resultado que terminan con ".xh"

Gracias, Bi

Respuesta

7

tratar

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

donde MYDIR es una cadena que contiene la ruta del directorio.

+0

necesita anclar esa expresión regular al final de la cadena y escapar de la. de alguna manera (me gusta usar una clase de personaje). Como es su expresión regular coincidirá con "abcxh.txt". Pruebe /[.]xh$/ en su lugar. –

+0

Gracias - ¡funcionó! –

+0

Extraño, tuve muchos problemas para obtener esta respuesta para formatear correctamente. Escapé del período, pero no se muestra (a menos que escape el escape). ¡También el <y> fueron una lucha! Gracias por tomar el $ ancla, no hice la prueba para ese caso. Reparado. –

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

también, todo Se puede acceder a los archivos en un directorio haciendo:

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

Alternativamente, puede usar el módulo Perl File :: find.

7

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

Está confundiendo un patrón de expresiones regulares con un patrón global.

#!/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

El punto que kevinadc y Sinan Unur están utilizando, pero no mencionar es que readdir() devuelve una lista de todas las entradas en el directorio cuando se le llama en el contexto de la lista. A continuación, puede utilizar cualquier operador de lista en eso. Es por eso que puede utilizar:

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

Así:

readdir MYDIR 

devuelve una lista de todos los archivos de MYDIR.

Y:

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

devuelve todos los elementos devueltos por readdir MYDIR que coincidan con los criterios allí.

+0

Modifique ese segundo cheque para que sea /\.xh$/ y estará revisando lo correcto. :) –

-1

En lugar de utilizar opendir y filtrado readdir (no se olvide de closedir!), En su lugar podría usar 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 no se preocupan por la eliminación de la $newpath prefijado a los resultados de glob , deshacerse de la map+splitpath.

+0

No es necesario el mapa o la ruta de división. O termina en .xh o no. El trabajo extra no cambia eso. –

+0

¿Eh? glob ("./ abc *") devuelve ("./abc.txt", "./abc.xh"); ¿De qué otra manera esperas mezclar eso hasta ("abc.txt")? – ephemient

Cuestiones relacionadas