【问题标题】:perl recursive file readperl 递归文件读取
【发布时间】:2011-11-23 03:54:36
【问题描述】:

我目前正在编写一个 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, &lt;FILE&gt; line 3.

而且我不完全确定我在做什么。想法?

预期输出(按顺序):

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

【问题讨论】:

    标签: perl file path


    【解决方案1】:

    一个问题是您没有使用核心模块File::Find。这旨在使目录遍历更容易。

    另一个问题是您将use strict; 注释掉了。

    另一个问题是您没有为getfn() 的参数创建my 变量。至少这是非常规的;使用好的变量名可以更容易理解代码。

    我收回之前关于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
    

    【讨论】:

    • 已编辑,我仍在努力解决File::Find。对我的新代码有意见吗?
    • 因为我改变了它——我拿走了你原来的东西并改变了它(被黑了)。而且这些变化不一定像我想要的那样精致,但你至少应该发现它是可识别的。
    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 2017-03-09
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    相关资源
    最近更新 更多