Perl 如何在从多个文件中搜索字符串时避免不确定循环
在我下面的程序中,我试图从文件夹中的任何文件中搜索字符串,但输出是连续打印的,而不是在要求的搜索后停止。有人能帮忙指出错误吗? i、 e.我试图从@files搜索字符串VoLTE SIPTX:[SIPTX-SIP]==>寄存器,但我没有得到所需的输出,但我得到了字符串的重复输出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
# #!/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:请打开一个新问题并显示完整的代码,以及一个复制该问题的简短示例数据文件。打开了一个标题为“无法从特定目录中的多个文件中搜索字符串”的新问题。谢谢