简体   繁体   English

zcat在命令行中工作,但不在perl脚本中工作

[英]zcat working in command line but not in perl script

Here is a part of my script: 这是我脚本的一部分:

foreach $i ( @contact_list ) {

    print "$i\n";

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

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

$e prints properly but $f gives a blank line even when $file_list2 has a match for $i . $e可以正确打印,但是即使$file_list2$i匹配, $i $f也会显示空白行。

Can anyone tell me why? 谁能告诉我为什么?

Your question leaves us guessing about many things, but a better overall approach would seem to be opening the file just once, and processing each line in Perl itself. 您的问题让我们猜测了很多事情,但是更好的整体方法似乎只是打开文件一次,并在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);

If you want to squeeze out more from the inner loop, compile the regexes from @contact_list into a separate array before the loop, or perhaps combine them into a single regex if all you care about is whether one of them matched. 如果要从内部循环中挤出更多内容,请在循环之前将@contact_list则表达式编译为单独的数组,或者如果您只关心它们中的一个是否匹配,则可以将它们组合为单个正则表达式。 If, on the other hand, you want to print all matches for one pattern only at the end when you know what they are, collect matches into one array per search expression, then loop them and print when you have grepped the whole set of input files. 另一方面,如果您只想在知道某个模式的结尾时才打印所有模式的所有匹配项,则将每个搜索表达式的匹配项收集到一个数组中,然后将它们循环并在对整个输入进行greped后打印文件。

Your problem is not reproducible without information about what's in $i , but I can guess that it contains some shell metacharacter which causes it to be processed by the shell before the grep runs. 没有有关$i内容的信息,您的问题就无法重现,但是我可以猜测,它包含一些外壳程序元字符,导致它在grep运行之前被外壳程序处理。

Always is better to use Perl's grep instead of using pipe : 使用Perl的grep总是比使用pipe更好:

@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
}

Best solution is not calling zcat, but using zlib library : http://perldoc.perl.org/IO/Zlib.html 最好的解决方案不是调用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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM