У меня есть журнал, в котором есть записи, занимающие несколько строк. Запись всегда начинается с даты в формате 2019-04-05 09:32:58,543. Единственный показатель того, что начинается следующая запись в журнале, это то, что у меня снова есть дата. В первой строке также есть уникальный идентификатор (XKcEpaUgg3QvsUTsQSuaIwAAATT в примере ниже).
С помощью https://stackoverflow.com/a/17988834/55070 я мог придумать awk-команду, которая довольно близка. Команда awk 'flag;/2019.*\| XKcEpaUgg3QvsUTsQSuaIwAAATT \|.*/{flag=1;next}/2019.*/{flag=0}' logfile
почти работает. Проблема в том, что он отображает не первую строку записи журнала, а строку, следующую за записью.
Поскольку второй шаблон в команде awk также соответствует первому шаблону, команда без следующего вернет только первую строку.
Один из примеров записи журнала:
2019-04-05 09:32:58,543 | some information for the first line | XKcEpaUgg3QvsUTsQSuaIwAAATT | more info |
first body line
second body line
some more information
2019-04-05 09:32:58,765 | some information for the next log entry | OTHER_ID | more info |
$ cat tst.awk
BEGIN { FS = " [|] " }
/^[0-9]{4}(-[0-9]{2}){2} ([0-9]{2}:){2}[0-9]{2},[0-9]{3} / { prt(); rec=$0; next }
{ rec = rec ORS $0 }
END { prt() }
function prt( flds) {
split(rec,flds)
if ( flds[3] == tgt ) {
print rec
}
}
$ awk -v tgt='XKcEpaUgg3QvsUTsQSuaIwAAATT' -f tst.awk file
2019-04-05 09:32:58,543 | some information for the first line | XKcEpaUgg3QvsUTsQSuaIwAAATT | more info |
first body line
second body line
some more information
$ awk -v tgt='OTHER_ID' -f tst.awk file
2019-04-05 09:32:58,765 | some information for the next log entry | OTHER_ID | more info |
Можно сделать проще:
date_ptn='^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9],[0-9]{3}'
myid = "XKcEpaUgg3QvsUTsQSuaIwAAATT"
awk -v id = "$myid" -v date_ptn = "$date_ptn" -F' \\| ' '$0 ~ date_ptn{p = $3 == id ? 1 : 0}p' file.txt
#2019-04-05 09:32:58,543 | some information for the first line | XKcEpaUgg3QvsUTsQSuaIwAAATT | more info |
#first body line
#
#second body line
#some more information
#
или просто $0 ~ date_ptn{ p=id==$3 }p
в строке awk.
На данный момент нет планов проверять какие-либо значения в линиях кузова.
Хорошая идея. Единственным недостатком является то, что вы не можете применить тот же подход, если хотите проверить какое-то значение в строках тела (или если 3-е поле не находится в первой строке каждой записи, но OP не показал нам это как возможность, так что может и не быть).