標籤:
在實際生產環境中,常常需要從後台日誌中截取報文,報文的形式類似於
<InterBOSS>
...
...
...
</InterBOSS>
一個後台日誌有多個報文,每個報文可由操作流水唯一確定。
以前用AWK寫過一個,程式如下:
beginline=`awk ‘BEGIN{i=0}{if($0~"<InterBOSS>") i=NR;if($0~"‘$oprseq‘"){print i;exit}}‘ $logname`endline=`awk ‘NR>‘$beginline‘{if($0~"</InterBOSS>"){print NR;exit}}‘ $logname`awk ‘NR>=‘$beginline‘&&NR<=‘$endline‘{print $0}‘ $logname
學了Perl以後,發現Perl很適合寫類似邏輯的指令碼,現改寫如下:
#!/usr/bin/perluse strict;my $flag=0;my $line;while(<>){ if(/<InterBOSS>/ or $flag eq 1){ $line .=$_; $flag=1; } if(/<\/InterBOSS>/){ $flag=0; if($line =~ $ARGV[0]){ print $line; last; } $line=‘‘; }}
思路是:
將每一個報文作為一個整體,放到$line中,然後驗證給定的操作流水是否在$line中,如果在,則輸出$line,如果不在,則將$line置為空白,繼續迴圈,直到遇到下一個報文的<InterBOSS>,$line才開始填充。
那麼如何確保<InterBOSS>和</InterBOSS>之間的行填充到$line中呢?在這裡,引入了一個變數$flag進行判斷,預設為0,在遇到<InterBOSS>時,將其置為1,在遇到</InterBOSS>時,又將其置為0。判斷是否填充的條件有兩個:一、匹配<InterBOSS>,二、$flag等於1,兩者只要符合一個即可,這樣就可確保<InterBOSS>和</InterBOSS>之間的行填充到$line中。
如何用Perl截取報文