2010-08-11 59 views
0

我在Perl中有一個腳本,用於搜索配置文件中的錯誤,但會打印出任何出現的錯誤。我需要匹配配置文件中的內容,並僅在最後一次發生錯誤時打印出來。有任何想法嗎?需要在Perl中打印最後一次出現的字符串


哇......我並不期待這麼多的迴應。我應該更清楚地說明這是用於發送警報給Nagios的Windows機箱上的日誌監視。這實際上是我的第一個Perl程序,所有這些信息都非常有幫助。有誰知道我可以如何應用這個任何在Wintel框中的尾部答案?

+3

到目前爲止你寫了些什麼? – msw 2010-08-11 23:31:16

+0

最簡單的方法,使用尾巴。例如perl my_perl_script_that_prints_out_errors.pl | tail -1 – zen 2010-08-12 03:26:25

回答

2

在大綱:

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

這捕獲所有的錯誤,但不打印,直到最後,當只有最後一個倖存。

4

另一種方式來做到這一點:

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

只是一個小小的評論:要存儲整行,使用'$ _'而不是'$ 1',或者使用'$ .'來存儲模式匹配的行號。很好的答案,我自己多次使用這種方法 – 2017-05-21 01:44:20

0

蠻力方法包括通過指向STDOUTtail來建立自己的管線。這可以讓你打印所有的錯誤,然後由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

使用正則表達式,當你想要一個模式的最後出現,將^.*在你的模式的前面。例如,替換最後一個X與Y中的輸入,使用

$ 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」)來允許額外的空格:目標是提高可讀性。

相關問題