Я работаю над проектом, который требует анализа файлов журналов. Я ищу быстрый алгоритм, который будет принимать такие групповые сообщения:
The temperature at P1 is 35F.
The temperature at P1 is 40F.
The temperature at P3 is 35F.
Logger stopped.
Logger started.
The temperature at P1 is 40F.
и выводит что-то в виде printf ():
"The temperature at P%d is %dF.", Int1, Int2"
{(1,35), (1, 40), (3, 35), (1,40)}
Алгоритм должен быть достаточно общим, чтобы распознавать практически любую загрузку данных в группах сообщений.
Я пробовал искать такую технологию, но даже не знаю, как правильно искать.





Я думаю, вы могли упустить из виду и пропустить fscanf () и sscanf (). Что является противоположностью fprintf () и sprintf ().
Это зависит от того, что вы пытаетесь сделать, если ваша цель - быстро сгенерировать ввод sprintf (), это работает. Если вы пытаетесь анализировать данные, возможно, вам подойдут и регулярные выражения.
@John: Я думаю, что вопрос относится к алгоритму, который действительно распознает шаблоны в файлах журналов и автоматически «угадывает» соответствующие строки формата и данные для них. Семейство *scanf не может сделать это само по себе, оно может помочь только после того, как образцы будут распознаны в первую очередь.
Вы не найдете инструмента, который мог бы просто принимать произвольный ввод, угадывать, какие данные вы хотите от него, и выдавать желаемый результат. Для меня это звучит как сильный ИИ.
Создавать что-то подобное даже для того, чтобы распознавать числа, становится очень непросто. Например, "123.456" одно число или два? Как насчет этого «123 456»? «35F» - это десятичное число и буква «F» или это шестнадцатеричное значение 0x35F? Вам нужно будет создать что-то, что будет анализировать так, как вам нужно. Вы можете сделать это с помощью регулярных выражений, или вы можете сделать это с помощью sscanf, или вы можете сделать это каким-то другим способом, но вам придется написать что-то особенное.
Однако с помощью базовых регулярных выражений вы можете сделать это самостоятельно. Это не будет волшебством, но и работы не так уж и много. Что-то вроде этого проанализирует интересующие вас строки и объединит их (Perl):
my @vals = ();
while (defined(my $line = <>))
{
if ($line =~ /The temperature at P(\d*) is (\d*)F./)
{
push(@vals, "(,)");
}
}
print "The temperature at P%d is %dF. {";
for (my $i = 0; $i < @vals; $i++)
{
print $vals[$i];
if ($i < @vals - 1)
{
print ",";
}
}
print "}\n";
Результатом этого является L
The temperature at P%d is %dF. {(1,35),(1,40),(3,35),(1,40)}
Вы можете сделать что-то подобное для каждого типа строки, которую вам нужно проанализировать. Вы даже можете читать эти регулярные выражения из файла, вместо того, чтобы кодировать каждое из них.
Спасибо за все отличные предложения. Крис, правильно. Я ищу универсальное решение для нормализации любого текста. Решение проблемы сводится к динамическому поиску паттернов в двух или более похожих строках. Почти как предсказание следующего элемента в наборе на основе двух предыдущих:
1: высота Эвереста 30000 футов
2: K2 имеет высоту 28000 футов
=> Какой узор? => Ответ:
[имя] высотой [число] футов
Теперь текстовый файл может содержать миллионы строк и тысячи шаблонов. Я хотел бы очень и очень быстро проанализировать файлы, найти шаблоны и собрать наборы данных, которые связаны с каждым шаблоном.
Я подумал о создании семантических хешей высокого уровня для представления шаблонов в строках сообщений. Я бы использовал токенизатор и дал каждому типу токенов определенный «вес». Затем я группировал хеши и оценивал их сходство. Как только группировка будет завершена, я буду собирать наборы данных.
Я надеялся, что мне не придется изобретать велосипед и я смогу повторно использовать то, что уже есть.
Клаус
Я не знаю какого-либо специального инструмента для этого. Когда мне нужно было решить аналогичную проблему, я пытался угадать регулярные выражения для соответствия строкам.
Затем я обработал файлы и отобразил только несогласованные строки. Если линия не совпадает, это означает, что шаблон неправильный и его следует настроить или добавить другой шаблон.
Примерно через час работы мне удалось найти ~ 20 шаблонов, соответствующих более чем 10000 строкам.
В вашем случае вы можете сначала «угадать», что одним из паттернов является "The temperature at P[1-3] is [0-9]{2}F.". Если вы повторно обработаете файл, удалив любую совпадающую строку, он останется "только":
Logger stopped.
Logger started.
Который затем можно сопоставить с "Logger (.+).".
Затем вы можете уточнить шаблоны и найти новые, соответствующие всему вашему журналу.
Обзор:
Алгоритм наивно !! отслеживает частоту слов по столбцам, при этом можно предположить, что каждую строку можно разделить на столбцы с помощью разделителя.
Пример ввода:
The dog jumped over the moon
The cat jumped over the moon
The moon jumped over the moon
The car jumped over the moon
Частоты:
Column 1: {The: 4}
Column 2: {car: 1, cat: 1, dog: 1, moon: 1}
Column 3: {jumped: 4}
Column 4: {over: 4}
Column 5: {the: 4}
Column 6: {moon: 4}
Мы могли бы дополнительно разделить эти списки частот, сгруппировав их по общему количеству полей, но в этом простом и удобном примере мы работаем только с фиксированным количеством полей (6).
Следующим шагом является перебор строк, которые генерировали эти списки частот, поэтому давайте рассмотрим первый пример.
/[a-z]+/i.Таким образом, просто перейдя на первую строку, мы можем составить следующее регулярное выражение:
/The ([a-z]+?) jumps over the moon/
Соображения:
Очевидно, что можно выбрать сканирование части или всего документа для первого прохода, если вы уверены, что списки частот будут достаточной выборкой всех данных.
Ложные срабатывания могут закрасться в результаты, и это будет зависеть от алгоритма фильтрации (размахивания руками), чтобы обеспечить лучший порог между статическими и динамическими полями или некоторой постобработки, выполненной человеком.
Общая идея, вероятно, хорошая, но фактическая реализация определенно повлияет на скорость и эффективность этого алгоритма.
@ Дерек Парк: Ну, даже сильный ИИ не мог быть уверен, что у него правильный ответ.
Возможно, можно было бы использовать какой-то механизм, похожий на сжатие:
Еще один пункт, который следует рассмотреть, - это сгруппировать строки по расстояние редактирования. Группировка похожих строк должна разбить проблему на блоки по одному шаблону для каждой группы.
На самом деле, если вам удастся написать это, пусть весь мир знает, я думаю, многим из нас понравится этот инструмент!
@ Андерс
Well, even a strong AI couldn't be sure it had the right answer.
Я думал, что достаточно сильный ИИ может обычно найти правильный ответ из контекста. например Сильный ИИ мог распознать, что «35F» в этом контексте - это температура, а не шестнадцатеричное число. Определенно есть случаи, когда даже сильный ИИ не сможет ответить. Это те же самые случаи, когда человек не сможет ответить (при условии, что очень сильный ИИ).
Конечно, это не имеет особого значения, поскольку у нас нет сильного ИИ. :)
http://www.logparser.com перенаправляет на форум IIS, который кажется довольно активным. Это официальный сайт "Инструментария парсера журналов" Габриэле Джузеппини. Хотя я никогда не использовал этот инструмент, я купил дешевую копию книги на Amazon Marketplace - сегодня она стоит всего 16 долларов. Ничто не сравнится с интерфейсом мертвого дерева для простого перелистывания страниц.
Заглянув на этот форум, я раньше не слышал о «Новом инструменте GUI для MS Log Parser, Log Parser Lizard» на http://www.lizardl.com/.
Ключевой проблемой, конечно же, является сложность вашей ГРАММАТИКИ. Чтобы использовать любой тип анализатора журналов, поскольку этот термин обычно используется, вам нужно точно знать, что вы сканируете, вы можете написать для него BNF. Много лет назад я прошел курс, основанный на «Книге драконов» Ахо-и-Ульмана, и хорошо изученная технология LALR может дать вам оптимальную скорость, если, конечно, у вас есть этот CFG.
С другой стороны, кажется, что вы достигли чего-то подобного искусственному интеллекту, а это совершенно другой порядок сложности.