在我的下面的程序中,我试图从文件夹中搜索字符串在文件夹中但是输出是以连续方式打印而不是在所需搜索后停止。有人可以帮助指出错误吗? 即我试图从@files搜索字符串“VoLTE SIPTX:[SIPTX-SIP] ==> REGISTER”,但我没有得到所需的输出,但我得到了我的字符串的重复输出。
# #!/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;
}
}
}
}
答案 0 :(得分:4)
以下是对您的代码的一些观察
您的调试方法似乎是随意尝试以查看它们是否有效。添加诊断print
语句会更有成效,因此您可以比较变量&#39;具有您期望的实际值
错误和警告消息是有用的信息,将use strict
注释掉以使其消失是愚蠢的
不要使用&符号&
调用子例程。这已经是20年来的最佳实践
整理和整理您的代码,以便您和您寻求帮助的任何人都可以轻松阅读。就目前而言,无法分析块的开始和结束位置而不计算括号字符{...}
变量应该尽可能接近my
声明它们的第一个使用点,而不是一次性位于文件或子程序的顶部
chomp
仅对从终端或文件中读取的字符串是必需的。它返回删除的字符数,而不是修剪后的字符串
if( $choice =~ /[Yy]/ ) { ... }
将仅检查字符串是否包含 Y
,因此如果操作员输入MARRY ME!
,则会返回 true < / em>的。您应该使用字符串相等eq
来检查是否已键入单个Y
字符
你不应该在双引号内单独使用标量变量。充其量它没有任何区别,只是为你的代码添加噪音;在最坏的情况下,它将完全改变变量的值。只是my $kw = $IMS_Message
是正确的
除非您需要对文件内容进行非顺序访问,否则最好使用while
循环逐行读取和处理它,而不是将整个内容读入数组并处理数组的每个元素。这也允许您使用内置行号变量$.
而不是实现自己的$l
主要问题是,您从$search
的结果派生了chomp $kw
,将$search
设置为chomp删除的字符数。这始终为零,因为$kw
是$IMS_Message
的副本,最后没有换行符。这意味着您要检查字符0
的每个文件的所有行,而不是您想要的消息。正确的方法是my $search = quotemeta($kw)
你已经到位但已经注释掉了,可能是因为你的政策是通过猜测来调试&#34;
修复这些问题,你的代码看起来应该是这样的
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;
}
}
}