Perl encuentra un archivo basado en su extensión a través de todos los subdirectorios

Tengo un segmento de código que funciona y encuentra todos los archivos .txt en un directorio determinado, pero no puedo hacer que busque en los subdirectorios.

Necesito mi script para hacer dos cosas

  1. escanear una carpeta y todos sus subdirectorios en busca de un archivo de texto
  2. imprime solo los últimos segmentos de su ruta

Por ejemplo, tengo un directorio estructurado

C:\abc\def\ghi\jkl\mnop.txt

Yo guión que apunta a la ruta C:\abc\def\. Luego pasa por cada una de las subcarpetas y encuentra mnop.txt y cualquier otro archivo de texto que se encuentre en esa carpeta.

Luego se imprime ghi\jkl\mnop.txt

Estoy usando esto, pero en realidad solo imprime el nombre del archivo y si el archivo se encuentra actualmente en ese directorio.

opendir(Dir, $location) or die "Failure Will Robertson!";
@reports = grep(/\.txt$/,readdir(Dir));
foreach $reports(@reports)
{
    my $files = "$location/$reports";
    open (res,$files) or die "could not open $files";
    print "$files\n";
}

preguntado el 08 de marzo de 13 a las 21:03

is $location debidamente poblada? -

sí, lo relleno arriba en el código (no se muestra) -

Si se supone que debe repetirse a través de los subdirectorios, escribir una subrutina recursiva probablemente funcionará. -

3 Respuestas

Creo que esta solución es más simple y más fácil de leer. Espero que sea útil !

#!/usr/bin/perl

use File::Find::Rule;

my @files = File::Find::Rule->file()
                            ->name( '*.txt' )
                            ->in( '/path/to/my/folder/' );

for my $file (@files) {
    print "file: $file\n";
}

Respondido 21 ago 15, 00:08

¿Qué pasa con el uso File::Find?

#!/usr/bin/env perl

use warnings;
use strict;
use File::Find;

# for example let location be tmp
my $location="tmp";

sub find_txt {
    my $F = $File::Find::name;

    if ($F =~ /txt$/ ) {
        print "$F\n";
    }
}


find({ wanted => \&find_txt, no_chdir=>1}, $location);

respondido 08 mar '13, 21:03

Esto obtiene exactamente lo que quiero. ¿Puedo hacer un foreach en el hallazgo? Básicamente por cada cosa que encuentra, ¿hace esto? - Heurístico

Mucho más fácil si solo usas File::Find módulo principal:

#!/usr/bin/perl
use strict;
use warnings FATAL => qw(all);

use File::Find;

my $Target = shift;

find(\&survey, @ARGV);

sub survey { 
    print "Found $File::Find::name\n" if ($_ eq $Target) 
}

Primer argumento: nombre sin ruta del archivo a buscar. Todos los argumentos posteriores son directorios para verificar. File::Find busca recursivamente, por lo que solo necesita nombrar la parte superior de un árbol, también se buscarán automáticamente todos los subdirectorios.

$File::Find::name es el nombre de ruta completo del archivo, por lo que podría restar su $location de eso si quieres una ruta relativa.

respondido 08 mar '13, 21:03

Así que tengo una ruta que se ve así C:\views\servername\reports\universes\Project ¿Cuál es la expresión regular para que diga \reports\universes\project? Gracias - Heurístico

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.