извлекать записи между заданным временем начала и окончания из нескольких файлов журнала - PullRequest
0 голосов
/ 03 июня 2018

у нас есть файлы журналов с миллионными записями в формате:

xyz, xyz, ГГГГ-ММ-ДД ЧЧ: ММ: СС , ....,

мы получим время начала и время окончания в формате: ГГГГММДДЧЧММСС в качестве входных данных для сценария оболочки.мы хотим извлечь записи из всех файлов журнала, отметка времени которых находится между временем начала и окончания.

Отдельная запись в журнале: abc, def, ghi, 2018-06-03 11: 00: 00 , ..., xyz

сценарий оболочки: xyz.sh '20180603112000' '20180604120000'

Ожидаемый результат: все записи, которые находятся между заданными двумя временными метками.

1 Ответ

0 голосов
/ 03 июня 2018
#!/bin/sh

d4="([0-9]{4})"
d2="([0-9]{2})"
pattern="$d4$d2$d2$d2$d2$d2"
replace='\1-\2-\3 \4:\5:\6'
from=$(echo "$1" | sed -r "s/$pattern/$replace/")
to=$(echo "$2" | sed -r "s/$pattern/$replace/")

sed -n "/$from/,\$p;/$to/q" file

В простом английском языке это первое совпадение $ from и первая строка, совпадающая с $ to.

В частности, скрипт сначала преобразует входные данные в метки времени, которые, как ожидается, появятся в файле,Затем sed выполняет итерацию файла без печати по умолчанию (-n), но выводит все, начиная с первой строки, чтобы соответствовать $, вплоть до последней строки ($), однако, если встречается $ to, sed завершит работу.

Хотя это решение не идеально.Он работает в предположении, что каждая секунда содержит хотя бы одну строку журнала.Или, по крайней мере, поиск секунд.Как правило, вам не нужно извлекать строки журнала с точностью до секунды, и я бы порекомендовал извлекать куски по часам или минутам.Если, конечно, у вас нет сумасшедшего количества строк журнала, в этом случае я думаю, что это предположение верно.Во-вторых, предполагается, что данные в строках журнала не содержат меток времени.Если сами данные содержат метки времени, то эта функциональность может прерваться.

Обновление: Мне не очень понравилось решение, которое я дал, поскольку оно печатает только первую строку, соответствующую $.Это было легко сделать, но, вероятно, не то, что вы хотите.Вот решение, которое останавливается прямо перед первой строкой, совпадающей с $:

sed -n "/$from/,\$p" file | sed "/$to/Q"

Вы можете сделать это с помощью одного вызова sed, но это немного сложнее понять:

sed -n "/$from/,\${/$to/Q;p}" file

И вот решение для включения всех строк, соответствующих $ на

sed -n "/$from/,\$p" file | sed "/$to/{/$to/{N};q}"

Объяснение новых частей: Q выйдет до автопечати, но так как я использовал p для печати, я должен был убедиться, что Qсрабатывает до p /$to/Q;p, или используйте отдельный вызов sed для более простого понимания решения.

Второе решение просто автоматически печатает, пока не встретит $ до /$to/.Затем он добавляет каждую последующую строку, соответствующую $, в patspace /$to/{N}.Финальный q печатает patspace и выходит из сед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...