2016-09-26 4 views
0

Вот часть моего сценария:zcat работает в командной строке, но не в PERL скрипт

foreach $i (@contact_list) { 

    print "$i\n"; 

    $e = "zcat $file_list2| grep $i"; 
    print "$e\n"; 

    $f = qx($e); 
    print "$f";          
} 

$e печатает правильно, но $f дает пустую строку, даже если $file_list2 имеет матч за $i.

Может ли кто-нибудь сказать мне, почему?

+0

Это редактировать резюме должен был читать «Пожалуйста, обратите внимание на уценку, когда вы добавляете код в свой ответ». Кроме того, добро пожаловать в переполнение стека. – simbabque

+1

Что в переменных? Почему вы не используете 'zgrep'? – tripleee

+0

Если входы большие (как предлагает формат на молнии), получение всех совпадений за один раз кажется лучшим подходом. – tripleee

ответ

0

Всегда лучше использовать Grep Perl вместо того, чтобы использовать трубу:

@lines = `zcat $file_list2`; # move output of zcat to array 
die('zcat error') if ($?);  # will exit script with error if zcat is problem 
# chomp(@lines)     # this will remove "\n" from each line 

foreach $i (@contact_list) { 

    print "$i\n"; 

    @ar = grep (/$i/, @lines); 
    print @ar; 
# print join("\n",@ar)."\n";  # in case of using chomp 
} 

Лучшее решение не называет zcat, но с использованием ZLIB библиотеки: http://perldoc.perl.org/IO/Zlib.html

use IO::Zlib; 

# .... 
# place your defiiniton of $file_list2 and @contact list here. 
# ... 

$fh = new IO::Zlib; $fh->open($file_list2, "rb") 
    or die("Cannot open $file_list2"); 
@lines = <$fh>; 
$fh->close; 

#chomp(@lines);     #remove "\n" symbols from lines 
foreach $i (@contact_list) { 

    print "$i\n"; 
    @ar = grep (/$i/, @lines); 
    print (@ar); 
# print join("\n",@ar)."\n"; #in case of using chomp 
} 
0

Ваш вопрос оставляет нам угадывание многих вещей, но лучший общий подход, казалось бы, открывает файл только один раз и обрабатывает каждую строку в самом Perl.

open(F, "zcat $file_list |") or die "$0: could not zcat: $!\n"; 
LINE: 
while (<F>) { 
    ######## FIXME: this could be optimized a great deal still 
    foreach my $i (@contact_list) { 
     if (m/$i/) { 
      print $_; 
      next LINE; 
     } 
    } 
} 
close (F); 

Если вы хотите выжать больше из внутреннего цикла, компиляция регулярных выражений из @contact_list в отдельный массив перед петлей, или, возможно, объединить их в единое регулярное выражение, если все, что вы заботитесь о том, является ли один из них соответствует. Если, с другой стороны, вы хотите распечатать все совпадения для одного шаблона только в конце, когда знаете, что это такое, собирайте совпадения в один массив для каждого выражения поиска, затем зацикливайте их и распечатайте, когда у вас есть grepped весь набор входных данных файлы.

Ваша проблема не воспроизводится без информации о том, что находится в $i, но я могу догадаться, что она содержит некоторый метасимвол оболочки, который заставляет его обрабатывать оболочку перед запуском grep.

+0

@contact_list - это массив, содержащий идентификаторы почты 355k, мне нужно проверить, присутствуют ли эти идентификаторы почты в моей базе данных, которая находится в zip-файле. , поэтому мне нужно проверить, присутствует ли каждый из этих идентификаторов почты 355k, а не в zip-файле. Кроме того, у самого zip-файла есть 4 миллиона записей, поэтому я стараюсь не открывать его и использовать zcat или zgrep. –

+0

Да, так что шансы на то, что цикл поиска 355k раз будет намного быстрее, чем цикл всего входного файла 355k раз. – tripleee

+0

Это не отвечает на вопрос и почти наверняка не решает проблему. – darch

Смежные вопросы