Как я могу рекурсивно считать каталоги в Perl?

Я хочу считать каталог рекурсивно для печати структуры данных в СТРАНИЦЕ HTML с Шаблоном:: Инструментарий. Но я зависаю в том, как сохранить Пути и Файлы в форме, которая может быть считана наше легкое.

Моя идея запускается как это

sub list_dirs{

     my ($rootPath) = @_;
     my (@paths);

     $rootPath .= '/' if($rootPath !~ /\/$/);

     for my $eachFile (glob($path.'*'))
     {

         if(-d $eachFile)
         {
              push (@paths, $eachFile);

              &list_dirs($eachFile);
          }
          else
          {
              push (@files, $eachFile);
          }
     }

 return @paths;
}

Как я мог решить эту проблему?

11
задан Przemek 19 March 2010 в 09:01
поделиться

4 ответа

Это должно помочь

 use strict;
 use warnings;
 use File::Find qw(finddepth);
 my @files;
 finddepth(sub {
      return if($_ eq '.' || $_ eq '..');
      push @files, $File::Find::name;
 }, '/my/dir/to/search');
19
ответ дан 3 December 2019 в 01:51
поделиться

Я думаю, у вас есть проблема в следующей строке вашего кода

for my $eachFile (glob($path.'*'))

Вы меняете переменную $ path на $ rootpath.

Путь будет сохранен правильно.

3
ответ дан 3 December 2019 в 01:51
поделиться

Ответ mdom объясняет, почему ваша первая попытка не удалась. Я также предлагаю вам рассмотреть более удобные альтернативы File :: Find . У CPAN есть несколько вариантов. Вот один.

use strict;
use warnings;
use File::Find::Rule;
my @paths = File::Find::Rule->in(@ARGV);

См. Также здесь:

А вот и переписанное рекурсивное решение. На заметку: используйте strict ; использовать предупреждения ; и использование блока области видимости для создания статической переменной для подпрограммы.

use strict;
use warnings;

print $_, "\n" for dir_listing(@ARGV);

{
    my @paths;
    sub dir_listing {
        my ($root) = @_;
        $root .= '/' unless $root =~ /\/$/;
        for my $f (glob "$root*"){
            push @paths, $f;
            dir_listing($f) if -d $f;
        }
        return @paths;
    }
}
5
ответ дан 3 December 2019 в 01:51
поделиться

Вы всегда должны использовать строгие правила и предупреждения, чтобы облегчить отладку кода. Perl предупредил бы вас, например, о том, что @files не объявлен. Но настоящая проблема с вашей функцией заключается в том, что вы объявляете лексическую переменную @paths при каждом рекурсивном вызове list_dirs и не возвращаете возвращаемое значение после шага рекурсии.

push @paths, list_dir($eachFile)

Если вы не хотите устанавливать дополнительные модули, возможно, вам поможет следующее решение:

use strict;
use warnings;
use File::Find qw(find);

sub list_dirs {
        my @dirs = @_;
        my @files;
        find({ wanted => sub { push @files, $_ } , no_chdir => 1 }, @dirs);
        return @files;
}
8
ответ дан 3 December 2019 в 01:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: