我有这个perl代码,我想要它做的是搜索字符串并在找到匹配时执行某些操作。
当找到匹配项时,我希望它将计数器增加1,这样它就不会再次遍历while循环了。一切都很好,除了柜台。不知怎的,它一直在进入循环。
我知道它有效,因为当我将计数器设置为1时,它不会进入循环。
#!/usr/bin/perl
use strict;
use warnings;
open (ERRORLOG, ">>/usr/local/bin/log.log") || die "failed to open errorlog file \n$!\n\a";
open (MESSAGES, "tail -1 /var/adm/messages |") || die "failed to open alarms file \n$!\n\a";
my $date=`date +"%d/%m/%y-%H:%M"`;
my $num_of_messages_sent;
while (my $line = <MESSAGES>) {
chomp($line);
if ($line =~ m/inetd|ypserv|cront|sys|kern|panic|scsi|ipmp|mpathd/i && $num_of_messages_sent < 1){
print ERRORLOG "$line\n";
print "$line\n";
print "$num_of_messages_sent\n";
do something
#$num_of_messages_sent = $num_of_messages_sent + 1;
$num_of_messages_sent++;
}
#$num_of_messages_sent = $num_of_messages_sent + 1;
#$num_of_messages_sent=0;
print "$num_of_messages_sent\n";
}
#$num_of_messages_sent = $num_of_messages_sent + 1;
$num_of_messages_sent=0;
close (ERRORLOG);
close (MESSAGES);
-----------------------second code----------------------------------------
#!/usr/bin/perl
use strict;
use warnings;
open (ERRORLOG, ">>/usr/local/bin/mcdl_errors.log") || die "failed to open errorlog file \n$!\n\a";
open (MESSAGES, "tail -1 /var/adm/messages | ") || die "failed to open alarms file \n$!\n\a";
## the last location checked is not at the end of messages file, we need to search the messages file
#count how many messages you need to send in 1 minute. we permit only 4 messages
#go over the messages file from the last location until the end
my $date=`date +"%d/%m/%y-%H:%M"`;
my $num_of_messages_sent=0;
my $line2compare = `more /usr/local/bin/line.txt`;
print "$line2compare\n";
while (my $line = <MESSAGES>) {
chomp($line);
if ($line =~ m/ypserv|cront|sys|kern|panic|scsi|ipmp|mpathd/i){
#print ERRORLOG "$line\n";
print "$line\n";
print "$num_of_messages_sent\n";
if ($line ne $line2compare) {
print ERRORLOG "$line\n";
print "$line2compare\n";
do something
$num_of_messages_sent++;
`echo $line > /usr/local/bin/line.txt`;
} else {
print "$line-Check this out\n";
}
print "$num_of_messages_sent\n";
last if $num_of_messages_sent>0;
}
}
close (ERRORLOG);
close (MESSAGES);
答案 0 :(得分:0)
我认为你永远不会输入if条件,因为你在你的文件上做了tail -1
,它只给你最后一行。如果最后一行与模式不匹配,则不要输入if条件,并且你的时间会立即结束,因为MESSAGES中只有一行。
您可以像这样打开文件:
open (MESSAGES, "/var/adm/messages") || die "failed to open alarms file \n$!\n\a";
删除if条件中的&& $num_of_messages_sent < 1
,并在循环结束时添加last if $num_of_messages_sent>0;
,如下所示:
while (my $line = <MESSAGES>) {
chomp($line);
if ($line =~ m/inetd|ypserv|cront|sys|kern|panic|scsi|ipmp|mpathd/i){
print ERRORLOG "$line\n";
print "$line\n";
print "$num_of_messages_sent\n";
do something
$num_of_messages_sent++;
}
print "$num_of_messages_sent\n";
last if $num_of_messages_sent>0;
}
PS:我不知道你的正则表达式是否有意,但|
字符被视为OR。如果您想匹配|
字符,则必须在其前加\
。
答案 1 :(得分:0)
两个问题:
首先使用tail -f
代替tail -1
。在退出循环之前,您只读取输出的一行。使用tail -f
将跟随输出,并且您的程序将继续循环,直到您使用last
语句。唯一的问题是如果您不使用{{1你的循环永远不会退出。相反,当写入该日志的过程消失时,您将坐在那里永远等待从未到来的行。
我通过查找可能在我的日志中的某种结束语句来解决这个问题。例如,如果您正在使用Tomcat,您可能会看到有关应用程序停止的信息。那应该是你退出循环的提示。
另一个问题是你没有初始化你的计数器:
last
当您尝试增加该值时,您将收到一条警告消息,并且您的程序可能会失败。代替:
my $num_of_messages_sent;