perl递归文件读取

发布于 2024-12-17 19:14:21 字数 1648 浏览 0 评论 0原文

我目前正在编写一个 Perl 程序,该程序读取给定的文件(命令行或硬编码),然后递归打印(如果扩展名为 .bragi 则打开)列出的文件和目录。例如:

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

where

master.bragi:

~/hello.bragi

and

hello.bragi:

subdir/

and

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,;第 3 行。

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

预期输出(按顺序):

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

I'm currently writing a Perl program that is to read a given file (either command-line or hard-coded) and then recursively print (and open if extension is .bragi) files and directories listed. For example:

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

where

master.bragi:

~/hello.bragi

and

hello.bragi:

subdir/

and

check.bragi:

main.c

The program would open master.bragi, see hello.bragi listed, open it to find a directory listed, open that directory, then repeat.

I currently have this code:

#!/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/");

Except I get some errors like No such file or directory at ./files.pl line 19, <FILE> line 3.

And I'm not entirely sure what I'm doing. Thoughts?

Expected output (in order):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以可爱出名 2024-12-24 19:14:21


一个问题是您没有使用核心模块 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


One problem is that you're not using the core module File::Find. This is designed to make directory traversals easier.

Another problem is that you have use strict; commented out.

Another problem is that you don't create my variables for the parameters to getfn(). At the very least that is aconventional; using good variable names makes it much easier to understand the code.

I take back the previous comment about File::Find. Here's a hacked version of your script that seems to work:

#!/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});

I created a test environment in the current directory like this:

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

The output of the command is:

file:   /Users/jleffler/tmp/soq/hello.bragi
DIR:    /Users/jleffler/tmp/soq/subdir
file:   /Users/jleffler/tmp/soq/subdir/main.c
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文