Как получить содержимое вложенных каталогов в Perl - PullRequest
2 голосов
/ 06 сентября 2010

Я пытаюсь написать скрипт, который будет обрабатывать определенные файлы.Данные организованы следующим образом: есть папка (назовем ее X), в которую будет помещен мой скрипт.В этой же папке есть подпапка с названием «данные».Это содержит еще несколько подпапок с различными именами, и каждая из них содержит много файлов (никаких других подпапок, только файлы).Мне нужно обработать все файлы в подпапке (точнее, запустить функцию для каждого файла), а затем объединить результаты для всех файлов в подпапке, поэтому для каждой папки есть один результат (независимо от того, сколько файлов он содержит).

Проблема в том, что я не могу получить доступ к файлам, поэтому я могу запустить на них свою функцию.Теперь у меня есть следующее:

$dirname = "data";

opendir ( DIR, $dirname ) || die "Error in opening dir $dirname\n";

while( ($dirname2 = readdir(DIR)) ) 
{
    next if $dirname2 eq ".";
    next if $dirname2 eq "..";

    opendir ( DIR2, $dirname2 ) || die "Error in opening dir $dirname2\n";

    while( ($file = readdir(DIR2)) ) 
    {
        next if $file eq ".";
        next if $file eq "..";

        print( "file:$file\n" );
    }

    closedir(DIR2);

}
closedir(DIR);

Это всегда дает сбой с сообщением «Ошибка при открытии каталога dir alex».'alex' оказывается первым каталогом в каталоге данных.У меня вопрос - где проблема?Это даже правильный путь, как добиться того, что я пытаюсь сделать?Я также беспокоюсь, что это мой сбой, если в папке данных есть файл, так как я не могу открыть его с помощью opendir, или я могу?

PS: извините за этот ужасный код Perl - явсе еще пытаюсь выучить этот язык.

Спасибо, Питер

Ответы [ 4 ]

2 голосов
/ 16 сентября 2010

Вот слегка исправленная версия того, что было опубликовано в вопросе.

use strict;
use warnings;
use autodie;
use File::Spec::Functions qw'catdir catfile';

my $dirname = "data";

{
    opendir my $dir_h, $dirname;

    while( my $dirname2 = readdir($dir_h) ){
        next if $dirname2 eq ".";
        next if $dirname2 eq "..";

        $dirname2 = catdir( $dirname, $dirname2 );
        next unless -d $dirname2;
        opendir my $dir_h2, $dirname2;

        while( my $file = readdir($dir_h2) ) 
        {
            next if $file eq ".";
            next if $file eq "..";

            $file = catfile($dirname2,$file);
            if( -f $file ){
              print( "file:$file\n" );
            }
        }
        # $dir_h2 automatically closes here
    }
    # $dir_h automatically closes here
}

Если вы собираетесь запускать его на версиях Perl более ранних, чем 5.12.0, вам следует обернуть условный цикл while с помощьюdefined().

    while( my $dirname2 = readdir($dir_h) ){
    while( defined( my $dirname2 = readdir($dir_h) ) ){
2 голосов
/ 06 сентября 2010

Вы можете попробовать File :: Path - Создать или удалить деревья каталогов

Поскольку я запускаю вашу программу, я думаю, что вы должны указать полный путь при открытии каталога, т.е.

opendir ( DIR2, $dirname.\\.$dirname2 ) || die "Error in opening dir $dirname2\n"; #running code on windows

Будет работать, попробуйте.

2 голосов
/ 06 сентября 2010

Вы уверены, что внутри папки существуют только папки? Добавить дополнительную проверку:

next if !(-d $dirname2);
2 голосов
/ 06 сентября 2010

вы можете использовать File :: Find для поиска файлов во вложенных каталогах

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...