awk многострочная проблема

Пытался написать awk-скрипт, который обрабатывает файл журнала, но не могу.

У меня есть файл, в котором есть строки, которые выглядят так:

[2011-07-29 04:44:37.100 INFO] AU/SUB1/Server:WebHits : Hits[ABC]=0; Hits[DEF]=876; Hits[THY]=0; Hits[SG]=891; Hits[XFRR]=1386
[2011-07-29 04:44:37.599 INFO] AU/SUB2/Server:WebHits : Hits[XARR]=0; Hits[XXX]=0; Hits[ABS]=0; Hits[SM]=0
[2011-07-29 04:44:37.699 INFO] AU/MAIN/Server:Main : Hits=254
[2011-07-29 04:44:38.100 INFO] AU/SUB1/Server:WebHits : Hits[ABC]=0; Hits[DEF]=1134; Hits[THY]=0; Hits[SG]=1153; Hits[XFRR]=426
[2011-07-29 04:44:38.599 INFO] AU/SUB2/Server:WebHits : Hits[XARR]=0; Hits[XXX]=0; Hits[ABS]=0; Hits[SM]=22
[2011-07-29 04:44:38.699 INFO] AU/MAIN/Server:Main : Hits=436

Как видите, три строки в секунду (всегда будет три строки в секунду). Я хотел бы объединить эти строки (по одной строке в секунду), чтобы сводка выглядела так, поэтому одна строка сводки коррелирует с тремя строками из входного лог-файла:

[2011-07-29 04:44:37 INFO] MainHits=254,ABC=0,DEF=876,THY=0,SG=891,XFRR=1386,XARR=0,XXX=0,ABS=0,SM=0
[2011-07-29 04:44:38 INFO] MainHits=436,ABC=0,DEF=1134,THY=0,SG=1153,XFRR=426,XARR=0,XXX=0,ABS=0,SM=22

Обратите внимание на названия мест проведения, например. «ABC, DEF, THY, SG и т. д.» могут изменяться динамически.

Любая помощь будет оценена по достоинству.


person Ben    schedule 01.08.2011    source источник
comment
И всегда будет 3 записи в секунду? Или может что иногда скатывается до 1 или 2, а может и 4,5? Можете ли вы определить его как любое изменение второго значения, когда вы хотите получить запись об активности для всех текущих тегов? (по состоянию на эту секунду). Удачи!   -  person shellter    schedule 01.08.2011
comment
Привет приют. Обновили вопрос. Да всегда будет 3 в секунду. И я хотел бы видеть одну сводную строку в секунду независимо от того, обновлялись ли данные или нет.   -  person Ben    schedule 01.08.2011
comment
вы написали «суммарную строку в секунду, независимо от того, обновлялись ли данные или нет». Это целая отдельная проблема. Если вы загружаете эти данные в базу данных, будет намного проще создавать там пустые записи. Удачи.   -  person shellter    schedule 01.08.2011


Ответы (2)


Решение в значительной степени зависит от формата ввода, который вы опубликовали:

awk '/Main :/ {
  sub(/\.[0-9]*/, x, $2)
  print $1, $2, $3, "Main" $NF, r
  r = x; next
  }
{
  gsub(/Hits\[/, x)
  gsub(/[];]/, x)
  for (i = 5; ++i <= NF;)
    r = r ? r "," $i : $i
  }' infile 
person Dimitre Radoulov    schedule 01.08.2011

Загадочное решение с использованием sed:

sed -e 'N;N;s/\n\[.\{28\}\]/;/g;s/\.... INFO/ INFO/;s!AU/SUB1/Server:WebHits : !!;s!AU/SUB2/Server:WebHits : !!;s!AU/MAIN/Server:Main : !!;s/ INFO\] \(.*\) Hits=\(.*\)/ INFO\] MainHits=\2 \1/;s/ Hits\[\([^]]*\)\]=\([^;]*\);/,\1=\2/g' infile

Это заслуживает некоторых объяснений, поэтому ниже приведена версия файла скрипта с комментариями. Он должен запускаться с 'sed -f script infile'

# Read 2 more lines, so we will have 3 lines are in the pattern space.
N
N
# Change the timestamps of the 2 extra lines by a ;.
s/\n\[.\{28\}\]/;/g
# Remove the milliseconds of the remaining timestamp, and the extra data of each line.
s/\.... INFO/ INFO/
s!AU/SUB1/Server:WebHits : !!
s!AU/SUB2/Server:WebHits : !!
s!AU/MAIN/Server:Main : !!
# Generate the MainHits data.
s/ INFO\] \(.*\) Hits=\(.*\)/ INFO\] MainHits=\2 \1/
# Format the Hits data.
s/ Hits\[\([^]]*\)\]=\([^;]*\);/,\1=\2/g
person jfg956    schedule 01.08.2011