perl递归文件读取

perl递归文件读取,perl,file,path,Perl,File,Path,我目前正在编写一个Perl程序,它读取给定的文件(命令行或硬编码),然后递归打印(如果扩展名是.bragi,则打开)列出的文件和目录。例如: ~ hello.bragi subdir/ ~/subdir check.bragi 在哪里 及 及 程序将打开master.bragi,请参见列出的hello.bragi,打开它以查找列出的目录,打开该目录,然后重复 我目前有以下代码: #!/usr/bin/perl -w use strict; use File::Base

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

~
    hello.bragi
    subdir/
~/subdir
    check.bragi
在哪里

程序将打开
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/");
一个问题是您没有使用核心模块。这是为了使目录遍历更容易。

另一个问题是,
使用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});
该命令的输出为:

file:   /Users/jleffler/tmp/soq/hello.bragi
DIR:    /Users/jleffler/tmp/soq/subdir
file:   /Users/jleffler/tmp/soq/subdir/main.c
一个问题是您没有使用核心模块。这是为了使目录遍历更容易。

另一个问题是,
使用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});
该命令的输出为:

file:   /Users/jleffler/tmp/soq/hello.bragi
DIR:    /Users/jleffler/tmp/soq/subdir
file:   /Users/jleffler/tmp/soq/subdir/main.c

已编辑,我仍在尝试计算
File::Find
。对我的新代码有何评论?因为我改变了它-我拿走了你原来的代码并改变了它(黑客攻击了它)。这些变化不一定像我希望的那样完美,但你至少应该会发现它是可识别的。经过编辑,我仍在努力找出
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