Получить полный валидный json из лога

Есть система на Linux. В ней есть лог. Внутри этого лога есть валидный json. Этот json там разбит на несколько строк. Я точно знаю, что внутри этого json есть ключ "id" со значением 12345. Как мне из этого лога получить весь json, содержащий этот ключ и значение? Проблем с чтением самого лога нет, только с выдёргиванием из него этого json.


Что я пробовал:

grep -zo "{.*\"id\".*12345.*}" log.log
grep -ez "{.*\"id\".*12345.*}" log.log

Нужного результата, к сожалению, не получил.


Пример лога для тестов:

2020-04-24 14:00:58.870+0300:Another string
2020-04-24 14:00:58.872+0300:Unusual json: {"some data": "another data"}
2020-04-24 14:00:58.891+0300:Answer from some service: {
 "event_id":"some id"
, "some information":"some value"
, "id":12345
, "timestamp":1587726058000
, "status":"ok"
,"some integer":100
, "category_scores":[
 {"id":"id1","value":123},
 {"id":"id2","score":234},
 {"id":"id3","score":100},
 {"id":"id4","score":299},
 {"id":"id5","score":600}
]
, "result":{"action":"some action","param":"0","action_code":"allow"}
, "service":{"request_id":1448
}}


Из этого примера надо получить:

{
 "event_id":"some id"
, "some information":"some value"
, "id":12345
, "timestamp":1587726058000
, "status":"ok"
,"some integer":100
, "category_scores":[
 {"id":"id1","value":123},
 {"id":"id2","score":234},
 {"id":"id3","score":100},
 {"id":"id4","score":299},
 {"id":"id5","score":600}
]
, "result":{"action":"some action","param":"0","action_code":"allow"}
, "service":{"request_id":1448
}}

Ответы (1 шт):

Автор решения: Senior Pomidor

предположим у нас есть файл log.log и внутри содержится ваш текст

Тогда команда выглядит следующим образом

cat log.log  | \
 sed -e "s/^\([0-9]\+\).*{/{/g" | \ 
 sed -e "s/^\([0-9]\+\).*//g" |  \
 tr -d '\n' \
 | jq " .| select(.id  == 12345)"
  1. удаляем все строки, где начинаются с цифр и есть {, оставляем знак {
  2. удаляем все строки, где начинаются с цифр
  3. удаляем корректор, чтобы лугче было нормалдизовть
  4. выбираем только те JSON, в котороых ксть родительный параметр .id, где значение равняется 12345

итого

{
  "event_id": "some id",
  "some information": "some value",
  "id": 12345,
  "timestamp": 1587726058000,
  "status": "ok",
  "some integer": 100,
  "category_scores": [
    {
      "id": "id1",
      "value": 123
    },
    {
      "id": "id2",
      "score": 234
    },
    {
      "id": "id3",
      "score": 100
    },
    {
      "id": "id4",
      "score": 299
    },
    {
      "id": "id5",
      "score": 600
    }
  ],
  "result": {
    "action": "some action",
    "param": "0",
    "action_code": "allow"
  },
  "service": {
    "request_id": 1448
  }
}

p.s. но если лог слишком большой, то лучше сделать sed -i filename

→ Ссылка