Perl рекурсивное чтение файлов - PullRequest
0 голосов
/ 23 ноября 2011

В настоящее время я пишу программу на Perl, которая должна прочитать заданный файл (из командной строки или жестко запрограммированный), а затем рекурсивно распечатать (и открыть, если расширение .bragi) перечисленные файлы и каталоги. Например:

~
    hello.bragi
    subdir/
~/subdir
    check.bragi

, где

master.bragi:

~/hello.bragi

и

hello.bragi:

subdir/

и

check.bragi:

main.c

Программа откроет master.bragi, см. Список hello.bragi, откройте его, чтобы найти каталог в списке, откройте этот каталог и повторите.

У меня сейчас есть этот код:

#!/usr/bin/perl -w

use strict;
use File::Basename;

sub isdir {
    return (-d $_[0]);
}

sub isfile {
    return (-f $_[0]);
}

sub getfn {
    my $path = $_[1];
    my (undef, undef, my $ext) = fileparse($_[0], qr"\..*");
    print "arg:\t".$path."\n";
    if ($ext eq ".bragi") {
    open FILE, "<", $path.$_[0] or die $!;
    my @lines = <FILE>;
    foreach my $line (@lines) {
        chomp($line);
        if (isfile($line)) {
        print "file:\t".$path.$line."\n";
        }
        if (isdir($line)) {
        print "DIR:\t".$line."\n";
        opendir my ($dh), $path.$line or die "Filename does not exist: $!";
        my @files = readdir $dh;
        closedir $dh;
        #print $files[0].":\t".$path.$line."/\n";
        foreach my $f (@files) {
            my $next = $path.$line."/";
            getfn($f, $next);
        }
        }
    }
    }
}

getfn("master.bragi", "/home/tekknolagi/twentytwelve/fs/");

За исключением того, что я получаю некоторые ошибки, такие как No such file or directory at ./files.pl line 19, <FILE> line 3.

И я не совсем уверен, что я делаю. Мысли?

Ожидаемый результат (по порядку):

master.bragi
hello.bragi
check.bragi
main.c

1 Ответ

3 голосов
/ 23 ноября 2011

Одна проблема в том, что вы не используете модуль ядра File::Find.Это сделано для облегчения прохождения каталогов.

Другая проблема заключается в том, что вы use strict; закомментировали.

Другая проблема заключается в том, что вы не создаете my переменных для параметров getfn().По крайней мере, это условно;Использование хороших имен переменных значительно облегчает понимание кода.

Я забрал предыдущий комментарий о File::Find.Вот взломанная версия вашего скрипта, которая, кажется, работает:

#!/usr/bin/perl -w

use strict;
use File::Basename;
use constant debug => 0;

sub isdir {
    return (-d $_[0]);
}

sub isfile {
    return (-f $_[0]);
}

my $level = 0;

sub getfn {
    my($file, $path) = @_;
    my (undef, undef, $ext) = fileparse($file, qr"\.[^.]+$");
    $level++;
    print "-->>getfn($level): $file : $path\n" if debug;
    print "arg:\t$file\t$path ($ext)\n" if debug;
    if ($ext eq ".bragi") {
        open my $FILE, "<", "$path/$file" or die "Failed to open $path/$file: $!";
        my @lines = <$FILE>;
        close $FILE;
        foreach my $line (@lines) {
            chomp($line);
            my $fullpath = "$path/$line";
            print "---- $fullpath\n" if debug;
            if (isfile($fullpath)) {
                print "file:\t$fullpath\n";
                getfn($line, $path);
            }
            elsif (isdir($fullpath)) {
                print "DIR:\t$fullpath\n";
                opendir my ($dh), $fullpath or
                    die "$fullpath does not exist or is not a directory: $!";
                my @files = readdir $dh;
                closedir $dh;
                foreach my $f (@files) {
                    getfn($f, "$fullpath");
                }
            }
        }
    }
    print "<<--getfn($level)\n" if debug;
    $level--;
}

getfn("master.bragi", $ENV{PWD});

Я создал тестовую среду в текущем каталоге следующим образом:

mkdir subdir
echo hello.bragi > master.bragi
echo subdir > hello.bragi
echo main.c > subdir/check.bragi
echo hello > subdir/main.c

Вывод команды:

file:   /Users/jleffler/tmp/soq/hello.bragi
DIR:    /Users/jleffler/tmp/soq/subdir
file:   /Users/jleffler/tmp/soq/subdir/main.c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...