2013-04-08 2 views
0

В настоящее время я пытаюсь создать парсер журнала, который берет из входного файла (.log) серию отчетов ping в следующем формате: (64 байт от 194.12.224.34: icmp_seq = 1 ttl = 47 time = 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 \?) 

Backslash нашел, где оператор ожидается на ./pingParseScript.pl линии 55, возле ") \" (Отсутствует оператор, прежде чем \) Backslash нашел, где оператор ожидается на ./pingParseScript.pl строка 55, рядом ") \" (Отсутствует оператор перед \?) Ошибка синтаксиса в строке ./pingParseScript.pl 55, рядом с "/ \ d + \ d + \ d + \ s + \ пакеты \ s + \ переданы , \ s + \ d + \ d + \ d + \ s + \ received, \ Замена шаблона не заканчивается ./pingParse Script.pl линия 55.

+2

Я думаю, что есть непревзойденное разделителем ранее в программе. У вас есть подкатегория '' '' '' '' '' '' '' '' '' случайно? – ikegami

+0

Вы показали только одну строку, но сообщения показывают ошибки в двух строках. – ikegami

+0

Обратите внимание, что ошибки в выражении 'elsif' могут содержать номер строки' if' в сообщении об ошибке. – ikegami

ответ

0

Фигурные скобки отсутствуют после, если заявление, оно должно быть написано так:

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 рядом») \ «сообщение об ошибке, относящееся к регулярному выражению. –

+0

Эта конкретная обратная косая черта, независимо от того, присутствует она или не изменяет сообщение об ошибке, к счастью. –

+0

Почему вы используете $ 8, $ 9, $ 16? Они не заполнены! вместо этого используйте $ 1, $ 2, $ 3. –

1

Я вижу две проблемы:

1) Изменить while(INPUT) по while (<INPUT>)

2) Последний, если необходимо включить {} и регулярное выражение воспоминания возобновляемые (от $1)

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

Кроме того, использование лексических дескрипторов файлов, в современных жемчужно образом:

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

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


close $input_fh; 
close $output_fh;