Perl从递归目录打开文件

时间:2012-06-14 17:17:52

标签: perl recursion

所以我的程序应该以递归方式遍历一个目录,然后对于目录中的每个文件,打开文件并搜索“错误”“失败”和“失败”字样。然后它应该写出这些单词出现的实例,以及这些单词之后的行上的其余字符,输出到命令提示符中指定的文件。我在确保程序对目录中找到的文件执行搜索时遇到了一些麻烦。现在它确实通过目录递归,甚至创建一个要写出来的文件,但是,它似乎没有搜索在递归中找到的文件。这是我的代码:

#!/usr/local/bin/perl

use warnings;
use strict;
use File::Find;


my $argument2 = $ARGV[0];
my $dir = "c:/program/Scripts/Directory1"; #directory to search through

open FILE, ">>$argument2" or die $!;   #file to write out 
my $unsuccessful = 0;
my @errors = ();
my @failures= ();
my @failures2 = ();
my @name = ();
my @file;
my $file;

my $filename;

opendir(DIR, $dir) or die $!;

while($file = readdir(DIR)){
next if($file =~ m/^\./);



foreach(0..$#file){
    print $_;
    open(FILELIST, '<', $_);    

    while(<FILELIST>){

    if (/Unsuccessful/i){
        $unsuccessful = 1;
    }
    if(/ERROR/ ){
        push(@errors, "ERROR in line $.\n");
        print  "\t\tERROR in line $.:$1\n" if (/Error\s+(.+)/);

    }
    if(/fail/i ){
        push(@failures, "ERROR in line $.\n");
        print FILE "ERROR in line $.:$1\n" if (/fail\s+(.+)/);

    }
    if(/failed/i ){
        push(@failures2, "ERROR in line $.\n");
        print FILE "ERROR in line $.:$1\n" if (/failed\s+(.+)/);

    }

    if ($unsuccessful){

    }

    }
    close FILELIST;


    }
}

closedir(DIR);
close FILE;

因此,为了澄清,我的问题是“while()”循环中包含的搜索似乎没有递归地在目录中找到的文件上执行。任何意见/建议/帮助你可以提供为什么会发生这种情况将非常有帮助。我是Perl的新手,所以一些示例代码也可以帮助我理解你想说的内容。非常感谢你。

2 个答案:

答案 0 :(得分:4)

通常,当我想对递归文件执行某些操作时,我会从find2perl开始。 -print使用wanted函数为我生成样板文件,我可以从中修改它以执行任何操作。

例如

# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
exit;
sub wanted {
    return unless -f $File::Find::name;
    return unless -R $File::Find::name;
    open (F,"<",$File::Find::name) or warn("Error opening $File::Find::name : $!\n");

    while(<F>) {
        if(m/error/) { print; }
        if(m/fail/) { print; }
    }   
}

答案 1 :(得分:1)

这是递归perl目录列表的示例。实际上,我可能会使用file :: find,或者只是grep -R,但我假设这是某种功课:


use strict;

my $dir = $ARGV[0];
my $level = 0;

depthFirstDirectoryList($dir, $level);

sub depthFirstDirectoryList{
    my ($dir, $level) = @_;

    opendir (my $ind, $dir) or die "Can't open $dir for reading: $!\n";

    while(my $file = readdir($ind)){
        if(-d "$dir/$file" && $file ne "." && $file ne ".."){
            depthFirstDirectoryList("$dir/$file", $level + 1);
        }
        else{
            no warnings 'uninitialized';
            print "\t" x $level . "file: $dir/$file\n";
        }
    }

}