0

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


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

4

4 回答 4

4

Another way to do it:

perl -n -e '$e = $1 if /(REGEX_HERE)/;  END{ print $e }' CONFIG_FILE_HERE
于 2010-08-12T01:43:37.770 回答
4

What exactly do you need to print? The line containing the error? More context than that? File::ReadBackwards can be helpful.

于 2010-08-12T05:26:28.293 回答
3

概述:

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

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

于 2010-08-11T23:41:20.050 回答
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

输出:

$ ./laster
而且==绝对不是这个

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

$ 回声 XABCXXXQQQQXX | perl -pe 's/^(.*)X/$1Y/'
XABCXXXQQQQXY

请注意,这^是多余的,因为正则表达式量词是贪婪的,但我喜欢把它放在那里以强调。

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

#! /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开关 (“multi-line”)^匹配逻辑行边界。

至此,我们知道了模式

/\A.* ^ .../

匹配看起来像某物的最后一行。否定的前瞻断言 (?!...)查找不是合法配置行的行。通常.匹配除换行符以外的任何字符,但/s开关(“单行”)解除了这个限制。指定[^\r\n]+,即一个或多个既不是回车也不是换行的字符,不允许匹配溢出到下一行。

环顾断言不会捕获,因此我们使用(.+?)$. 在这种情况下使用它是安全的原因.是因为我们知道当前行是错误的,并且非贪婪量词+?会尽快停止匹配,在这种情况下是当前逻辑行的结尾。

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

于 2010-08-12T12:32:38.957 回答