Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何在从多个文件中搜索字符串时避免不确定循环_Perl - Fatal编程技术网

Perl 如何在从多个文件中搜索字符串时避免不确定循环

Perl 如何在从多个文件中搜索字符串时避免不确定循环,perl,Perl,在我下面的程序中,我试图从文件夹中的任何文件中搜索字符串,但输出是连续打印的,而不是在要求的搜索后停止。有人能帮忙指出错误吗? i、 e.我试图从@files搜索字符串VoLTE SIPTX:[SIPTX-SIP]==>寄存器,但我没有得到所需的输出,但我得到了字符串的重复输出 # #!/usr/bin/perl # use strict; use warnings; &IMS_Compare_Message(); sub IMS_Compare_Message { pri

在我下面的程序中,我试图从文件夹中的任何文件中搜索字符串,但输出是连续打印的,而不是在要求的搜索后停止。有人能帮忙指出错误吗? i、 e.我试图从@files搜索字符串VoLTE SIPTX:[SIPTX-SIP]==>寄存器,但我没有得到所需的输出,但我得到了字符串的重复输出

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

&IMS_Compare_Message();
sub IMS_Compare_Message
{

    print "Entering the value i.e. the IMS Message to compare with";
    my $value = '';
    my $choice = '';
    my $loop = '';

  print "\nThe script path & name is $0\n";
  print "\nPlease enter desired number to select any of the following   


    (1) Start Comparing REGISTER message !!

    (2) Start Comparing SUBSCRIBE message

        (3) Start Comparing INVITE message \n";

    $value = <STDIN>;

    if ($value == 1 )
    {

        print "\n Start Comparing REGISTER message\n\n";
        $IMS_Message = "VoLTE SIPTX: [SIPTX-SIP] ==>  REGISTER";
        #chomp ($IMS_Message);
    }

    elsif ($value == 2)
    {

        print "\n SUBSCRIBE message Flow\n\n";


    }
    elsif ($value == 3)
    {

        print "\n INVITE message Flow\n\n";


    }
    else 
    {
        print "\nThe input is not valid!\n";
        print "\nDo you want to continue selecting a Automation Mode again (Y or N)?\n";

        $choice = <STDIN>;
        if( $choice =~ /[Yy]/) {        
            test_loop();
        } else {
            exit;
        }
    }

my $kw = "$IMS_Message";
my @files = grep {-f} (<*main_log>);

foreach my $file (@files) 
{
    open(my $fh, '<', $file) or die $!;
    my @content = <$fh>;
    close($fh);
    my $l = 0;
    $search = chomp ($kw);
    #my $search = quotemeta($kw);
        foreach (@content) 
            { # go through every line for this keyword
                $l++;
                if (/$search/)
                    {
                        printf 'Found keyword %s in file %s, line %d:%s'.$/, $kw, $file, $l, $_
                    }
            }
}
}
修改后

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


    print "Entering the value i.e. the IMS Message to compare with";
    my $value = '';
    my $choice = '';
    my $loop = '';
    my $IMS_Message = '';
    my $search = '';
    my $kw = '';

    print "\nThe script path & name is $0\n";
    print "\nPlease enter desired number to select any of the following   

    (1) Start Comparing REGISTER message !!
    (2) Start Comparing SUBSCRIBE message
        (3) Start Comparing INVITE message \n";

    $value = <STDIN>;

    if ($value == 1 )
    {

        print "\n Start Comparing REGISTER message\n\n";
        $IMS_Message = "VoLTE SIPTX: [SIPTX-SIP] ==>  REGISTER";
        #chomp ($IMS_Message);
    }

    elsif ($value == 2)
    {

        print "\n SUBSCRIBE message Flow\n\n";


    }
    elsif ($value == 3)
    {

        print "\n INVITE message Flow\n\n";


    }
    else 
    {
        print "\nThe input is not valid!\n";
        print "\nDo you want to continue selecting a Automation Mode again (Y or N)?\n";

        $choice = <STDIN>;
        if( $choice eq /[Yy]/) {        
            test_loop();
        } else {
            exit;
        }


    $kw = $IMS_Message;
    $search = qr/\Q$kw/;

    for my $file ( grep { -f } glob '*main_log' ) {
    open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};
    while ( <$fh> ) {
        if ( /$search/ ) {
            printf "Found keyword %s in file %s, line %d: %s\n", $kw, $file, $., $_;
            last;
        }
    }
}
}

下面是对您的代码的一些观察

您的调试方法似乎是随机尝试一些东西,看看它们是否有效。添加诊断打印语句将更有成效,这样您就可以将变量的实际值与预期值进行比较

错误和警告消息都是有用的信息,用严格的注释来消除它们是愚蠢的

不要用符号AND&调用子例程。20年来,这并不是最好的做法

将代码整齐、简洁地放好,以便您和任何需要帮助的人都能轻松阅读。目前,如果不计算大括号字符{…},就无法判断块的开始和结束位置

变量应该用my声明,尽可能接近它们的第一个使用点,而不是一次全部在文件或子例程的顶部

chomp仅对从终端或文件读取的字符串是必需的。它返回删除的字符数,而不是经过修剪的字符串

如果$choice=~/[Yy]/{…}将只检查字符串是否包含Y,因此如果运算符输入mary ME!它会变成现实。您应该使用字符串相等eq来检查是否键入了单个Y字符

不应该将标量变量单独放在双引号内。充其量也不会有什么区别,只会给你的代码增加噪音;在最坏的情况下,它将完全改变变量的值。只是我的$kw=$IMS_消息是正确的

除非需要对文件内容进行非顺序访问,否则最好使用while循环逐行读取和处理,而不是将整个内容读入数组并处理数组中的每个元素。这还允许您使用内置的行号变量$。而不是实现你自己的$l

主要问题是您从chomp$kw的结果中派生了$search,它将$search设置为chomp删除的字符数。这始终为零,因为$kw是$IMS_消息的副本,该消息末尾没有换行符。这意味着您正在检查每个文件的所有行中是否有字符0,而不是要检查的消息。正确的方法是我的$search=quotemeta$kw,您已经准备好了,但是已经注释掉了,这可能是由于您的猜测调试策略

修复这些问题后,您的代码应该如下所示

my $search = qr/\Q$kw/;

for my $file ( grep { -f } glob '*main_log' ) {

    open my $fh, '<', $file or die qq{Unable to open "$file" for input: $!};

    while ( <$fh> ) {
        if ( /$search/ ) {
            printf "Found keyword %s in file %s, line %d: %s\n", $kw, $file, $., $_;
            last;
        }
    }
}

标题和问题说明了不同的事情。你需要什么帮助还不清楚。这就是:严格使用;不要那样做!chomp不会像你认为的那样返回。它在a附近做什么呢?我刚去掉了它的嘴,但它仍然在;同样的输出严格的使用要点是,它会生成错误消息,引导您找到代码中的基本错误。没有添加use strict是错误的,但是写下它然后注释掉它是完全愚蠢的,因为你说你想保留所有这些错误。当您选择忽略Perl本身内置的基本帮助时,向全世界寻求代码帮助是荒谬的。。谢谢你的指导。我做了你建议的修改,但仍然没有得到我想要的任何输出。。我一点输出都没有。我已经添加了上面的代码。@rocky:请打开一个新问题并显示完整的代码,以及一个复制该问题的简短示例数据文件。打开了一个标题为“无法从特定目录中的多个文件中搜索字符串”的新问题。谢谢