2011-02-23 22 views
7

Tengo un script de Perl que he escrito para buscar archivos presentes en mis carpetas de Windows, recursivamente. Ingresé el texto de búsqueda como el argumento del tiempo de ejecución del script de Perl para encontrar un archivo que tenga este texto en su nombre. El script perl es el siguiente:¿Cómo encontrar archivos/carpetas recursivamente en Perl script?

use Cwd; 

$file1 = @ARGV[0];  

#@res1 = glob "*test*"; 
#@res1 = glob "$file1*"; 
@res1 = map { Cwd::abs_path($_) } glob "$file1*"; 
foreach (@res1) 
{ 
    print "$_\n"; 
} 

Pero esto no busca todos los subdirectorios recursivamente. Sé que glob no coincide recursivamente.
Así intentado usar el módulo File::Find y la función find(\&wanted, @directories);

pero me dio un error diciendo find() indefinido. Por lo que leí de la ayuda, pensé que la función find() está definida por defecto en la instalación de Perl, con algunos códigos básicos para encontrar carpetas/archivos. ¿No es correcto?

Preguntas es, en el script de Perl anterior, ¿cómo busco archivos/carpetas recursivamente?

En segundas preguntas, encontré que perldoc <module> help no tiene ejemplos sobre el uso de una determinada función en ese módulo, lo que lo dejaría en claro.

¿Puede indicar alguna buena ayuda/documento/libro para usar varias funciones perl de diferentes módulos perl con ejemplos claros del uso de esas funciones del módulo?

+0

Mi método de esta pregunta http://stackoverflow.com/questions/4979310/extended-for-subdirectories-rename-files-and-directories-add-prefix podría ayudar. La tarea en este caso fue cambiar el nombre de todos los archivos y carpetas en un directorio y todos los subdirectorios. El método podría modificarse fácilmente para sus usos. –

Respuesta

4

Una alternativa sería utilizar find2perl para crear el inicio de la secuencia de comandos para usted. Puede activar un comando de búsqueda como,

find . -type f -name "*test*" -print 

Para un script de perl equivalente. Usted acaba de poner find2perl en lugar de encontrar. Utiliza File :: Find debajo del capó, pero te pone en marcha rápidamente.

+0

Gracias. Aprende este find2perl y me pareció muy útil para obtener algunas secuencias de comandos predeterminadas de búsqueda de archivos con las que puedo jugar. – goldenmean

+0

De hecho, creo que la respuesta de Alessandro es realmente mejor, pero para que te vayas, find2perl es realmente útil. –

3

Si no les importa usar el módulo CPAN, Path::Class puede hacer el trabajo por usted:

use Path::Class; 

my @files; 
dir('.')->recurse(callback => sub { 
    my $file = shift; 
    if($file =~ /some text/) { 
     push @files, $file->absolute->stringify; 
    } 
}); 

for my $file (@files) { 
    # ... 
} 
+0

BTW, buenas noticias, en mi prueba, esto parece funcionar también en una copia nueva de OSX Lion (10.8.5) hasta mi última prueba que hice en OSX El Capitan (10.11) sin tener que instalar el módulo . Entonces, si fueras como yo, construyendo un instalador que dependiera de que esto funcionara por defecto, lo hace. – Volomike

15

Otro módulo excelente a utilizar es File::Find::Rule que oculta parte de la complejidad de File::Find la vez que expone la misma funcionalidad rica .

use File::Find::Rule; 
use Cwd; 

my $cwd = getcwd(); 
my $filelist; 

sub buildFileIndex { 
    open ($filelist, ">", "filelist.txt") || die $!; 

    # File find rule 
    my $excludeDirs = File::Find::Rule->directory 
           ->name('demo', 'test', 'sample', '3rdParty') # Provide specific list of directories to *not* scan 
           ->prune   # don't go into it 
           ->discard;  # don't report it 

    my $includeFiles = File::Find::Rule->file 
          ->name('*.txt', '*.csv'); # search by file extensions 

    my @files = File::Find::Rule->or($excludeDirs, $includeFiles) 
           ->in($cwd); 

    print $filelist map { "$_\n" } @files; 
    return \$filelist; 
} 
Cuestiones relacionadas