Используя 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 );
}