【问题标题】:My perl script isn't working, I have a feeling it's the grep command我的 perl 脚本不起作用,我感觉是 grep 命令
【发布时间】:2016-05-06 19:08:38
【问题描述】:

我正在尝试在一个文件中搜索 如果其他文件包含这些数字,则编号并发布

#!/usr/bin/perl
open(file, "textIds.txt"); #
        @file = <file>;         #file looking into
#        close file;            #
while(<>){
        $temp = $_;
        $temp =~ tr/|/\t/;      #puts tab between name and id
        @arrayTemp = split("\t", $temp);
        @found=grep{/$arrayTemp[1]/} <file>;
        if (defined $found[0]){
        #if (grep{/$arrayTemp[1]/} <file>){
                print $_;
        }
        @found=();
}
print "\n";
close file;

#the input file lines have the format of 
#John|7791  154
#Smith|5432 290
#Conor|6590 897

#And in the file the format is 
#5432
#7791
#6590
#23140

【问题讨论】:

  • 打印出$arrayTemp[1],你就会知道问题出在哪里了。
  • 您已经在脚本的第三行将整个文件内容吞入@file,但随后您又试图在 grep 语句中从中读取更多行。此时,&lt;file&gt; 没有更多内容可以返回给您,并且每次都返回undef。如果你在代码中启用use warnings;,Perl 会告诉你的。
  • @PaulL 您使用warnings(和strict,即使您没有说出来)的观点是正确的,但是这段代码实际上不会产生任何警告。在这种情况下,我们不知道命令行参数是什么,所以很难说空文件句柄会做什么。但即使是while (&lt;file&gt;) 也无济于事;代码根本不会进入循环。
  • Perl script grep的可能重复
  • @MattJacob 你是绝对正确的。我很抱歉。我搞砸了上下文 - 我没有考虑到 grep 在 &lt;&gt; 运算符上强制使用列表上下文。如果它在标量上下文中工作,那么它将返回undef,Perl 肯定会警告不要使用它。尽管如此,(假设只有数字的四行是textIDs.txt 的内容,另一个文件在命令行上传递),&lt;file&gt; 将简单地返回一个空列表,这 grep 非常高兴在没有警告的情况下使用。谢谢指正。

标签: perl grep


【解决方案1】:

您的脚本中存在一些问题。

  1. 总是包括use strict; 和use warnings;。 这会提前告诉您脚本中的奇怪之处。
  2. 切勿使用裸字作为文件句柄,因为它们是全局标识符。使用三参数开 改为:open( my $fh, '&lt;', 'testIds.txt');
  3. use autodie; 或检查打开是否有效。
  4. 您读取testIds.txt 并将其存储到数组@file 但稍后(在您的grep 中)您是 再次尝试从该文件(句柄)中读取(使用&lt;file&gt;)。正如@PaulL 所说,这将永远 给undef (false) 因为文件已经被读取了。
  5. 无需将| 替换为制表符,然后在制表符处拆分。您可以在 选项卡和管道(假设“John|7791 154”真的“John|7791\t154”)。
  6. 您在谈论“输入文件”和“在文件中”时并没有确切说明哪个是哪个。 我假设您的“textIds.txt”是只有数字的那个,另一个 输入文件 是 从 STDIN 读取的一项(其中包含 |)。

考虑到这一点,您的脚本可以写成:

#!/usr/bin/perl
use strict;
use warnings;

# Open 'textIds.txt' and slurp it into the array @file:
open( my $fh, '<', 'textIds.txt') or die "cannot open file: $!\n";
my @file = <$fh>;
close($fh);

# iterate over STDIN and compare with lines from 'textIds.txt':
while( my $line = <>) {
    # split "John|7791\t154" into ("John", "7791", "154"):
    my ($name, $number1, $number2) = split(/\||\t/, $line);

    # compare $number1 to each member of @file and print if found:
    if ( grep( /$number1/, @file) ) {
        print $line;
    }
}

【讨论】:

    猜你喜欢
    • 2014-02-18
    • 1970-01-01
    • 2023-02-05
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 2015-06-03
    • 2020-08-10
    相关资源
    最近更新 更多