2013-04-08 46 views
0

我目前正在嘗試創建一個日誌解析器,它從輸入文件(.log)中獲取一系列ping報告,格式如下:(從194.12.224.34開始的64個字節:icmp_seq = 1 ttl = 47時間= 66.7毫秒)並建立輸出文件(.csv)。Perl RegEx錯誤

經過多次嘗試,我遇到了下面的錯誤。我的同事給了我他的代碼(下面),它的寫法不同,但本質上是一樣的。他的代碼給出了同樣的錯誤,儘管他的工作很自然地適用於相同的任務。任何援助將不勝感激!

我現在認爲我的前兩個正則表達式的工作正常,第三個是問題。下面就是我試圖解析:

120包轉發,120接收,0%的丟包率,時間119247ms RTT最小/平均/最大/ MDEV = 65.944/67.381/72.714/1.728毫秒

我首先發布在這裏,如果缺少某些東西,請致歉。

$INPUT = "ping.log"; 
$OUTPUT = "pingParsed.csv"; 

# > operator puts the write function in overwrite mode rather than append. 
open (INPUT, '<', $INPUT); 
open (OUTPUT, '>', $OUTPUT); 

while (<INPUT>) { 

# if (timestamp regex) 
if(/(\w{3})\s+(\w{3})\s+(\d+)\s+(\d+):(\d+):(\d+)\s+GMT\s+(\2013)/) { 


# print OUTPUT (date regex variables, $1 = Day, $2 = Month, $3 = Day, $4 = hour, $7 = year) 
print OUTPUT "$1 , $2 , $3 , $4 , $7"; 

$headers = "IP, Seq, Time"; 

print OUTPUT "$headers"; 

} 

# if (ping info regex, $1 = IP address, $2 = Seq, $3 = Time) 
if (m/icmp_seq= 
(\S+) 
\s+ttl= 
(\S+) 
\s+time= 
(\S+) /x) # x allows use of whitespaces and comments in the regex. 
{ 
    print "$1, $2, $3\n"; 
} 


# if (regex for total ping info - I think this is line 55.) 
if (/\d+\d+\d+\s+\packets\s+\transmitted,\s+\d+\d+\d+\s+\received,\s+(\d+)\s+\packet\s+\loss,\s+time\s+(\d+)\ms\s+\min\avg\max\mdev\s+=\s+(\(S+)\\/\(S+)\\/(S+)\\/\(\S+)\s+\ms/) { 
headers: 
print ("$15 = packet loss(%), $22 = time(ms), $28 = rttmin, $33 = arg, $35 = max, $37 = ndev"); 

print OUTPUT ($15, $22, $28, $33, $35, $37); 

} 


} 

close $INPUT; 
close $OUTPUT; 

錯誤:?

Backslash found where operator expected at ./pingParseScript.pl line 55, near "/\d+\d+\d+\s+\packets\s+\transmitted 
    (Missing operator before \?) 

反斜槓發現其中運營商預計將在./pingParseScript.pl線55,接近 「)\」 (缺少運算符之前\) 反斜槓發現其中運營商預計將在./pingParseScript.pl line 55,near「)\」 (Missing operator before \?) 語法錯誤在./pingParseScript.pl第55行,靠近「/ \ d + \ d + \ d + \ s + \ packets \ s + \傳輸,\ s + \ d + \ d + \ d + \ s + \ received,\ 替代模式未在./pingParse處終止Script.pl線55

+2

我想有一個無與倫比的分隔符早前在節目中。你有沒有一個叫做's','m'或'y'的子? – ikegami 2013-04-08 18:44:34

+0

您只顯示一行,但消息顯示兩行錯誤。 – ikegami 2013-04-08 18:46:14

+0

注意'elsif'表達式中的錯誤可以在錯誤消息中包含'if'的行號。 – ikegami 2013-04-08 18:47:01

回答

0

花括號if語句後失蹤,應該這樣寫:

if(/icmp_seq=(\S+)\s+ttl=(\S+)\s+time=(\S+)/) 
{ 

#if(/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+icmp_seq=(\S+)\s+ttl=\d+\s+time=(\S+)/) 


print OUTPUT "$8, $10, $16"; 
} 

或者這樣:

print OUTPUT "$8, $10, $16" 
    if(/icmp_seq=(\S+)\s+ttl=(\S+)\s+time=(\S+)/); 

而且

while (INPUT) 

應該這樣寫:

while (<INPUT>) 

更換你如果有這樣的說法:

if(/icmp_seq= 
(\S+) 
\s+ttl= 
(\S+) 
\s+time= 
(\S+)/x) #x allows use of whitespaces and comments in your regex 
{ 
    print "$1, $2, $3\n"; 
} 
+0

我按照您的建議更正了錯誤,但仍然在'X'附近得到'反斜槓找到操作符所期望的位置')\「與正則表達式相關的錯誤消息。 – 2013-04-08 19:46:04

+0

這個特殊的反斜槓,不管是否存在,也不會不會改變錯誤信息。 – 2013-04-08 20:07:58

+0

你爲什麼用8美元,9美元,16美元?他們沒有填滿!改用$ 1,$ 2,$ 3。 – 2013-04-08 20:10:07

1

我看到兩個問題:

1)更改while(INPUT)通過while (<INPUT>)

2)最後,如果必須包括{}和正則表達式記憶重新啓動(從$1

if(/icmp_seq=(\S+)\s+ttl=(\S+)\s+time=(\S+)/) { 
    print OUTPUT "$1, $2, $3"; 
} 

此外,使用詞法文件句柄,在現代的Perl方式:

open my $input_fh, '<', $INPUT or die $!; 
open my $output_fh, '>', $OUTPUT or die $!; 

while(<$input_fh>) { 
    # ... 
} 


close $input_fh; 
close $output_fh;