需要在Perl中打印最后一次出现的字符串

时间:2010-08-11 23:29:54

标签: perl perl-io

我在Perl中有一个脚本,用于搜索配置文件中的错误,但它会打印出任何错误。我需要匹配配置文件中的内容,并仅在上次错误发生时打印出来。有什么想法吗?


哇...我没想到会有这么多回应。我应该更清楚地说明这是用于向Nagios发送警报的Windows框上的日志监控。这实际上是我的第一个Perl程序,所有这些信息都非常有用。有谁知道如何在wintel盒子上应用这个尾部答案?

4 个答案:

答案 0 :(得分:4)

另一种方法:

perl -n -e '$e = $1 if /(REGEX_HERE)/;  END{ print $e }' CONFIG_FILE_HERE

答案 1 :(得分:4)

您到底需要打印什么?包含错误的行?比那更多的背景? File::ReadBackwards可能会有所帮助。

答案 2 :(得分:3)

概述:

my $errinfo;
while (<>)
{
    $errinfo = "whatever" if (m/the error pattern/);
}
print "error: $errinfo\n" if ($errinfo);

这会捕获所有错误,但直到最后才打印,只有最后一个存在。

答案 3 :(得分:0)

蛮力方法涉及通过将STDOUT指向tail来设置自己的管道。这允许您打印所有错误,然后最多tail担心只允许最后一个错误。

您没有指定,因此我假设法律配置行的格式为

Name = some value

匹配很简单:

  • ^(从行首开始)
  • \w+(一个或多个“字符”)
  • \s+(其次是强制性空格)
  • =(后跟等号)
  • \s+(更强制性的空格)
  • .+(某些强制性值)
  • $(在行尾完成)

将它们粘合在一起,我们得到了

#! /usr/bin/perl

use warnings;
use strict;

# for demo only
*ARGV = *DATA;

my $pid = open STDOUT, "|-", "tail", "-1" or die "$0: open: $!";
while (<>) {
  print unless /^ \w+ \s+ = \s+ .+ $/x;
}

close STDOUT or warn "$0: close: $!";

__DATA__
This = assignment is ok
But := not this
And == definitely not this

输出:

$ ./lasterr 
And == definitely not this

使用正则表达式,当您想要最后一次出现模式时,请将^.*放在模式的前面。例如,要用Y替换输入中的最后一个X,请使用

$ echo XABCXXXQQQXX | perl -pe 's/^(.*)X/$1Y/'
XABCXXXQQQXY

请注意,^是多余的,因为regular-expression quantifiers是贪婪的,但我喜欢在那里强调它。

将此技术应用于您的问题,您可以在配置文件中搜索包含错误的最后一行,如以下程序所示:

#! /usr/bin/perl

use warnings;
use strict;

local $_ = do { local $/; scalar <DATA> };
if (/\A.* ^(?! \w+ \s+ = \s+ [^\r\n]+ $) (.+?)$/smx) {
  print $1, "\n";
}

__DATA__
This = assignment is ok
But := not this
And == definitely not this

正则表达式的语法有点不同,因为$_包含多行,但原理是相同的。 \A^类似,但它在要搜索的字符串的开头仅匹配 。使用/m switch (“multi-line”)^匹配逻辑行边界。

到目前为止,我们知道模式

/\A.* ^ .../

匹配看起来像某个东西的最后一行。 negative look-ahead assertion (?!...)会查找合法配置行的行。通常.匹配除换行符之外的任何字符,但/s switch (“single line”)会解除此限制。指定[^\r\n]+,即一个或多个既不回车也不换行的字符,不允许匹配溢出到下一行。

Look-around assertions无法捕获,因此我们使用(.+?)$抓取违规行。在这种情况下使用.是安全的原因是因为我们知道当前行是坏的并且non-greedy quantifier +?尽快停止匹配,在这种情况下是当前逻辑行的结束

所有这些正则表达式都使用/x switch (“extended mode”)来允许额外的空格:目的是提高可读性。