0

我目前正在尝试创建一个日志解析器,它从输入文件(.log)中获取以下格式的一系列 ping 报告:(来自 194.12.224.34 的 64 个字节:icmp_seq=1 ttl=47 time=66.7 ms)和构建一个输出文件(.csv)。

经过多次尝试,我遇到了以下错误。我的同事给了我他的代码(如下),它的写法不同,但本质上是相同的。他的代码给出了同样的错误,尽管他的代码自然地在同样的任务中工作得很好。任何帮助将不胜感激!

我现在相信我的前两个正则表达式的工作正常,第三个是问题。以下是我试图解析的内容:

传输 120 个数据包,接收 120 个数据包,0% 数据包丢失,时间 119247ms rtt min/avg/max/mdev = 65.944/67.381/72.714/1.728 ms

我在这里的第一篇文章,如果有什么遗漏,请见谅。

$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 第 55 行,靠近 ")\" 处找到运算符预期的位置(\ 之前缺少运算符?) ./pingParseScript.pl 第 55 行的语法错误,靠近 "/\d+\d+\d+\s+\packets\s+\transmitted,\s+\d+\d+\d+\s+\received,\ 替换模式未终止于./pingParseScript.pl 第 55 行。

4

2 回答 2

1

我看到两个问题:

1)while(INPUT)改变while (<INPUT>)

2)最后一个 if 必须包含{}并且正则表达式内存重新启动(从$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;
于 2013-04-08T18:57:01.140 回答
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 语句:

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"; 
}
于 2013-04-08T18:54:32.620 回答