Я хочу извлечь все журналы между двумя отметками времени. Некоторые строки могут не иметь метки времени, но я хочу, чтобы эти строки тоже. Короче говоря, я хочу каждую строку, которая попадает под две отметки времени. Моя структура журнала выглядит так:
[2014-04-07 23:59:58] CheckForCallAction [ERROR] Exception caught in +CheckForCallAction :: null
--Checking user--
Post
[2014-04-08 00:00:03] MobileAppRequestFilter [DEBUG] Action requested checkforcall
Предположим, я хочу извлечь все между 2014-04-07 23:00
и 2014-04-08 02:00
.
Обратите внимание, что отметка времени начала или окончания времени может отсутствовать в журнале, но я хочу каждую строку между этими двумя отметками времени.
text-processing
sed
awk
grep
Amit
источник
источник
date -d
команду и используя его для построения шаблона поиска.Ответы:
Вы можете использовать
awk
для этого:Где:
-F
определяет символы[
и]
как разделители полей, используя регулярное выражение$0
ссылается на полную строку$2
ссылается на поле датыp
используется в качестве логической переменной, которая защищает фактическую печать$0 ~ /regex/
верно, если регулярное выражение соответствует$0
>=
используется для лексикографического сравнения строк (эквивалентно, например,strcmp()
)вариации
Приведенная выше командная строка реализует сопоставление правого интервала времени . Чтобы получить семантику с закрытым интервалом, просто увеличьте правильную дату, например:
Если вы хотите сопоставить метки времени в другом формате, вам нужно изменить
$0 ~ /^\[/
подвыражение. Обратите внимание, что раньше игнорировались строки без каких-либо отметок времени из логики включения / выключения печати.Например, для формата отметки времени
YYYY-MM-DD HH24:MI:SS
(без[]
скобок) вы можете изменить команду следующим образом:(обратите внимание, что также изменен разделитель полей - переход к пустому / непустому, по умолчанию)
источник
$1 ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}/ && $2 ~/[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/ { Time = $1" "$2; if (Time >= "2014-04-07 23:00" ) { p=1 } if (Time >= "2014-04-08 02:00:01" ) { p=0 } } p
code
$ 0 ~ / ^ [az | AZ] {4} - [0-9] {2} - [0-9] {4} [0-2] [0-9 ]: [0-5] [0-9]: [0-5] [0-9] / && $ 1 "" $ 2> = "Апр-07-2014 11:00" {p = 1} $ 0 ~ / ^ [az | AZ] {4} - [0-9] {2} - [0-9] {4} [0-2] [0-9]: [0-5] [0-9]: [0 -5] [0-9] / && $ 1 "" $ 2> = "Апр-07-2014 12:00:01" {p = 0},code
но не работаетПроверьте
dategrep
на https://github.com/mdom/dategrepОписание:
Примеры использования:
Хотя это ограничение может сделать это неподходящим для вашего точного вопроса:
источник
Одной из альтернатив
awk
или нестандартных инструментов является использование GNUgrep
для контекстных команд. GNUgrep
позволяет указать количество строк после положительного совпадения для печати-A
и предыдущие строки для печати-B
Например:Вышесказанное в сущности говорит
grep
напечатать 10000 строк, которые следуют за линией, соответствующей шаблону, с которого вы хотите начать, эффективно заставляя ваш вывод начинаться с того места, куда вы хотите, и идти до конца (надеюсь), тогда как втораяegrep
в pipe указывает ему печатать только строку с конечным разделителем и 10 000 строк перед ним. Конечный результат этих двух начинается с того места, где вы хотите, и не проходит, где вы сказали, чтобы он остановился.10000 - это просто число, которое я придумал, смело меняйте его на миллион, если вы думаете, что ваш результат будет слишком длинным.
источник
sed
что также ищет буквальные совпадения.dategrep
это, пожалуй, самый правильный ответ из всех приведенных (поскольку вам нужно быть «неясным» в отношении того, какие временные метки вы будете принимать), но, как говорится в ответе, я просто упомянул его в качестве альтернативы. Тем не менее, если журнал достаточно активен, чтобы генерировать достаточно выходных данных, чтобы гарантировать сокращение, он, вероятно, также будет иметь какую- то запись для данного периода времени.Используя sed:
Скопируйте это в файл. Если вы не хотите видеть информацию об отладке, отладка отправляется в stderr, поэтому просто добавьте «2> / dev / null»
источник