0

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

#!/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 的新手,所以一些示例代码也可以帮助我理解你想说的话。非常感谢。

4

2 回答 2

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; }
    }   
}
于 2012-06-14T17:39:19.273 回答
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";
        }
    }

}


于 2012-06-14T17:44:28.100 回答