Используя Perl, вставьте в массив список файлов в каталоге, за исключением нескольких файлов выбора, основанных на имени файла

Я загружаю тарбол через веб-страницу, помещаю его в /tmp/, затем спрашиваю этот скрипт (который будет вызываться через crontab):

1.) извлечь его

2.) построить список всех файлов (только файлы и рекурсивно) в каталоге

3.) найдите в каждом файле строку и напечатайте это имя файла и строку с соответствующей строкой в ​​файле.

Все работает до той части, где я хочу построить список файлов в (извлеченный tarball) каталог. Если я не поставлю "!" перед регулярным выражением в строке 6 в моем коде (соответствует только файлам.bak, .conf, .cfg), тогда я получаю только дюжину файлов в @filelist (как я и ожидал, напечатанных кодом в строке 13).

Однако если я поставлю "!" перед моим регулярным выражением в строке 6 (предназначенной для соответствия всем, кроме этих файлов) в строке 13 будут напечатаны все имена файлов, включая файлы с расширениями.bak,.conf и.cfg.

Как я могу получить коллекцию имен файлов в (извлеченном tarball) каталоге, кроме тех, которые меня просто не беспокоят?

Это мой код, грубо говоря (урезанный, непроверенный). Я новичок в Perl, поэтому я прошу прощения за уродство того, что у меня здесь, но это то, что есть.

 1    sub loadFiles {
 2        my $dir=shift;
 3        find(\&recurDir,"$dir");
 4    }
 5    sub recurDir {
 6        if ( $File::Find::name =~ /(\.bak|\.conf|\.cfg)$/i ) {
 7            push @filelist, $File::Find::name;
 8        }
 9        print "$File::Find::name\n";
10    }
11    sub searcher {
12        my $file=$_;
13        print "Searching $file\n";
14    }
15    my $tarball = '/tmp/mytarball.tar.gz';
16    my $ae = Archive::Extract->new( archive=>$tarball ) || die ("$!");
17    $ae->extract( to=>$UPLOAD_DIR ) || die ("$ae->error");
18    my $dir_loc = File::Spec->catfile( $UPLOAD_DIR, $ae->files->[0]);
19    loadFiles("$dir_loc");
20    find(\&searcher, @filelist);

2 ответа

Решение

Вы добавляете каталог в @filelist в строке 7 вы печатаете все файлы в этом каталоге и его подкаталогах в строке 13.

Строка 6 должна быть:

if ( -f $File::Find::name && $File::Find::name !~ /\.(?:bak|conf|cfg)\z/i ) {

Строка 13 должна быть:

searcher($_) for @filelist;

searcher должно быть:

sub searcher {
   my ($file) = @_;
   print "Searching $file\n";
}

Избегая глобальных изменений, все выглядит так:

sub loadFiles {
    my $dir=shift;

    my @filelist;
    my $wanted = sub {
        return if $File::Find::name =~ /\.(?:bak|conf|cfg)\z/i;
        return if !-f $File::Find::name;
        push @filelist, $File::Find::name;
    };

    find($wanted, $dir);
    return @filelist;
}

sub searcher {
    my $file=shift;
    print "Searching $file\n";
}

searcher($_) for loadFiles($dir_loc);

(Технически, вы могли бы сделать searcher($File::Find::name); прямо вместо pushдобавив его в массив, а затем зацикливая массив.)

my $tarball = '/tmp/mytarball.tar.gz';
my $ae = Archive::Extract->new( archive=>$tarball ) || die ("$!");
my @files;
$ae->extract( to=>$UPLOAD_DIR ) || die ("$ae->error");
for my $file (@{$ae->files}) {
  push @files, $file if $file =~ /(\.bak|\.conf|\.cfg)$/i );
}
Другие вопросы по тегам