MortyRick
@MortyRick

Как правильно распарсить логи с помощью bash?

Добрый день.

Появилось необходимость в логе вида:
RESULT=xxxxx, TIME=2020-01-20 18:43:12, HOST=xxxxxxxxxxx, NAME=xxxxxxxx

что бы в значение TIME время записывалось в абсолютно дебильном виде - TIME=18:43:12.000 +0700 Mon Jan 20 2020. Никак иначе биллинг не принимает.
Быстро и прям в лоб накодил вот такого монстра:
#!/bin/bash

date_prefix=`date -d  '1 hour ago' "+ %z %a %b %d %G"`

cat LOG.csv | while read line
do
date_setup=`echo ${line} | grep -o TIME=................... | awk -F" " -v var="${date_prefix}" {'print $2".000" var'}`
echo ${line} | sed "s/TIME=.................../TIME=$date_setup/g" >> LOG_new.csv
done


Лог файл из 1000 строк переколбасил за 6 сек. Но в бою логов будет 100 000 - 10 минут ждать когда все это сконверится, слишком долго.

Подскажите как еще подойти к этому вопросу? Возможно perl или python с такой задачей справится быстрее.
Возможно этот "дебильный" формат времен - это вообще какой-то стандарт и в него можно ковертнуть одной командой.
  • Вопрос задан
  • 770 просмотров
Пригласить эксперта
Ответы на вопрос 2
trapwalker
@trapwalker
Программист, энтузиаст
Вот такая штука будет работать примерно со скоростью мегабайт в секунду.
cat oldlogfile.log | py -x "', '.join(['='.join((k, datetime.datetime.strptime(v, '%Y-%m-%d %H:%M:%S').strftime('%H:%M:%S.000 +0700 %a %b %d %Y')) if k == 'TIME' else (k, v)) for k, v in ((kv.split('=') for kv in x.split(', ')))])" > newlogfile.log

Измерял так:
yes "RESULT=xxxxx, TIME=2020-01-20 18:43:12, HOST=xxxxxxxxxxx, NAME=xxxxxxxx" \
  | pv \
  | py -x "', '.join(['='.join((k, datetime.datetime.strptime(v, '%Y-%m-%d %H:%M:%S').strftime('%H:%M:%S.000 +0700 %a %b %d %Y')) if k == 'TIME' else (k, v)) for k, v in ((kv.split('=') for kv in x.split(', ')))])" \
  > /dev/null

Зато на порядок понятнее и можно по человечески формат подправить.
Ответ написан
@Karpion
У Вас на каждую строчку лога - запускается несколько программ/процессов. И выводной файл каждый раз открывается и закрывается. Неудивительно, что это извращение тормозит.

Надо как-то так:
Убираем cat. Всё делает awk.
Функцию "grep -o TIME=..." можно перенести в awk, у него есть хороший инструмент для этого.
Запуск "date" - тоже сделать в awk, распарсить дату ручками.

Ну или хотя бы уберите ">> LOG_new.csv" из цикла - это прекрасно делается снаружи, после "done"; в кр.случае - надо будет взять это дело в скобки.

Вы бы дали пример лога, было бы проще. Хорошо бы с пояснениями.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы