2010-06-01 4 views
3

У меня есть файл журнала, который имеет первые несколько символов каждой строки в качестве метки времени.Диапазон дат Задача

2010-06-01 04: 56: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 04: 56: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 04: 56: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 04: 56: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 05: 22: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 05: 22: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 05: 22: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 05: 22: 02802 DEBUG {Thread-27} Некоторые текстовые сообщения

2010- 06-01 06: 43: 02,802 INFO {Thread-27} Некоторое текстовое сообщение

2010-06-01 06: 43: 02803 INFO {Thread-27} Некоторые текстовые сообщения

2010-06-01 06: 43: 02804 INFO {Thread-27} Некоторые текстовые сообщения

2010-06-01 06: 43: 02804 INFO {Thread-27} Некоторые текстовые сообщения

2010-06-01 06: 43: 02809 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 06: 43: 02,809 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 06: 43: 02809 DEBUG {Thread-27} Некоторые текстовые сообщения

2010-06-01 07: 08: 02809 DEBUG { Thread-27} Некоторые текстовые сообщения

2010-06-01 07: 08: 02809 DEBUG {Thread-27} Некоторые текстовые сообщения

Моя цель, чтобы найти все такие строки, которые имеют метку 1 hr до текущего времени.

Как это можно достичь?

+1

Разве что за час до текущего часа, минуты и секунды? Или вас просто интересуют все записи, зарегистрированные в 6 часов утра, если текущий час равен 7 утра? – Zaid

ответ

1

Поскольку временные метки будут отсортированы, вы можете попробовать своего рода Binary Search с твист.

Так как в основном линии не будут иметь одинаковую длину, вы можете просто искать определенное смещение, искать новые строки (или любой другой ограничитель строки), который появляется до и после (после ИЛИ после и один после, что), вы получаете линию кандидата.Теперь сравните дату на линии с той, которую вы ищете, и решите, искать ли снова, или просто осмотрите окрестности этой линии.

При определении того, какое смещение нужно искать дальше, вы можете попытаться использовать что-то похожее на то, что делает Interpolation Search, т. Е. Принять решение о смещении, основанном на разнице между временем, которое вы получили, и временем, которое вы ищете.

Это должно быть намного быстрее, чем линейный поиск.

Для примера, чтобы сделать бинарный поиск в файлах с помощью Perl: http://perl.plover.com/yak/lightweight-db/materials/slides/slide024.html

+0

Решения Perl, как правило, больше ориентированы на обработку текста. Видя, что OP только после регистрации нескольких строк, это бинарный поиск действительно стоит? – Zaid

+0

@ Zaid: Действительно ли имеет значение, что OP пытается использовать perl для этого? ОП никогда не говорил, что файл журнала был небольшим, поэтому я не знаю, откуда у вас это. Конечно, я согласен с тем, что проблема OP действительно пыталась определить, что такое время журнала для определенной строки, но это не ясно из вопроса. – 2010-06-01 14:12:27

+0

Я не сказал, что файл журнала был небольшим. Я сказал, что ОП только после нескольких строк. Необходимость OP очевидна: определите те линии с отметками времени, которые находятся в пределах часа текущего времени. Вопрос помечен 'perl', поэтому я предполагаю, что он хочет получить ответ в Perl ... Я не говорю, что ваш ответ неверен, но я никогда не видел такой проблемы, связанной с бинарным поиском, вероятно, потому, что нужно было бы загрузить весь файл в память. – Zaid

4

Модуль DateTime хорошо подходит для нужд этой проблемы:

use strict; 
use warnings; 
use DateTime; 

my $oneHourAgo = DateTime->now()->subtract(hours => 1); 
my $threshold = join ' ', $oneHourAgo->ymd, $oneHourAgo->hms; # Time as string 

open my $logFile, '<', 'logfile.txt'; 

while (my $log = <$logFile>) { 

    chomp $log; 
    my ($time) = split /,/, $log;  # Gets current log's time 

    print $log if $time ge $threshold; # String-compares log's time to threshold 
} 

close $logFile; 
+0

+1 для использования 'ge', а не (более дорого) преобразование каждой метки времени для вычисления объекта DateTime :: Duration. – pilcrow

0

делает заказ, что строки выводятся дело? Если вы не против иметь их с последними в первую очередь, вы можете подумать об использовании File::ReadBackwards. Продолжайте читать назад до тех пор, пока линия не станет более одного часа, а затем остановится. Если вы хотите их в определенном порядке, вы можете сохранить их в массиве и распечатать их, как хотите. (Это предполагает, что это более или менее стандартный файл журнала с последними записями в конце файла.)

Смежные вопросы