Объединение JSON с разными именами ключей - PullRequest
0 голосов
/ 05 мая 2020

РЕДАКТИРОВАТЬ: собираюсь упростить мой вопрос и примеры JSON до только соответствующих элементов.

Создание playbook в Ansible, и одна задача, которую я пытаюсь выполнить, включает извлечение данных от 4 отдельных конечных точек Qradar API и пытается объединить некоторые детали с каждой из конечных точек.

4 разных json источника для каждой из конечных точек:

  • «regex_properties. json»: имеет уникальный «идентификатор», и мне нужно указать «имя» и значения «property_type».
  • «log_source_types. json»: имеет уникальное поле «id», и мне нужно указать его «name»
  • «log_sources. json»: Имеет уникальное поле «id» и может включать поле «type_id», если оно входит в группу log_source_type (соответствует «id» выше). Потребуется поле «name» из этого, а также потенциально «last_event_time» для фильтрации (но можно обойтись без него).
  • «property_expressions. json»: имеет уникальное поле «идентификатор». Также имеет значение log_source_type_id и / или log_source_id, которому сопоставляется каждый regex_property_identifier. Эти значения сопоставляются с уникальными идентификаторами в других журналах

Примеры из лабораторной работы:

regex_properties.json
[
  {
    "identifier": "59723052-d96c-4cef-ba7b-69d426602e04",
    "property_type": "numeric",
    "name": "indexTotalSize",
  }
]

log_sources.json
[
  {
    "id": 64,
    "name": "SIM Audit-2 :: eng-qradar-aio-01",
    "type_id": 105,
    "last_event_time": 1588628234930,
  }
]

log_source_types.json
[
    "name": "SIM Audit",
    "id": 105
  },
]

property_expressions.json
[
  {
    "identifier": "0311c65b-d5b5-483e-943f-b539543a8e95",
    "log_source_type_id": 105,
    "log_source_id": 65,
    "regex_property_identifier": "59723052-d96c-4cef-ba7b-69d426602e04",
  }
]

Я хотел бы получить эти 4 источника и вывести файл с следующие данные связаны выражениями property_expressions. json:

  • «name» и «property_type» regex_property. json (переименовано в regex_name или что-то подобное)
  • "name" из log_sources. json и log_source_types. json (переименовано в ls_name и lst_name соответственно)

Например, как показано ниже

merged_example.json
[
  {
    "identifier": "0311c65b-d5b5-483e-943f-b539543a8e95",
    "log_source_type_id": 105,
    "log_source_id": 65,
    "regex_property_identifier": "59723052-d96c-4cef-ba7b-69d426602e04",
    "property_type": "numeric",
    "regex_name": "indexTotalSize",
    "lst_name": "SIM Audit",
    "ls_name": "SIM Audit-2 :: eng-qradar-aio-01",
  }
]

Или в CSV с те же данные, которые являются конечной целью экспорта, но могут подождать.

Я попытался переименовать «идентификатор» в «regex_property_identifier» в regex_properties. json, затем с помощью 'jq -s regex_properties. json property_expressions. json ', но я все еще вижу, что оба содержимого представляют собой отдельные массивы в одном и том же файле output /.

Я пробовал использовать ansible и делал что-то вроде:

  - name: use JQ to reformat json to csv
    shell: cat /tmp/property_expressions.json | jq -r '.[]' | jq 'select(.enabled == true)' | jq '[.identifier,.regex_property_identifier,.log_source_id,.log_source_type_id] | @csv' > /tmp/props.csv

  - name: Read CSV into dictionary
    read_csv:
      path: "/tmp/props.csv"
      fieldnames: "prop_id,regex_id,ls_id,lst_id"
      delimiter: ","
    register: props

  - name: Loop Prop Dictionary and replace in CSV the regex_id
    replace:
      path: "/tmp/props.csv"
      regexp: "{{ item.regex_id }}"
      replace: "{{ regex_properties.json | json_query(regex_name_q) }},{{ regex_properties.json | json_query(regex_type_q) }}"
    loop: "{{ props.list }}"
    vars:
      regex_name_q: "{{ item.regex_id }}.name"
      regex_type_q: "{{ item.regex_id }}.property_type"

Чтобы просто сделать CSV и найти / заменить термины элемент за элементом. Но если бы я мог сделать это в массивах JSON, это было бы чище.

1 Ответ

0 голосов
/ 06 мая 2020

Предполагая незначительные ошибки в примерах JSON в вопросе, следующий сценарий bash выдает результат, как показано:

#!/bin/bash

jq -n \
 --argfile lst log_source_types.json \
 --argfile ls  log_sources.json \
 --argfile pe  property_expressions.json \
 --argfile rp  regex_properties.json '
  [ range(0, $pe|length) as $i
    | {identifier: $pe[$i].identifier,
       log_source_type_id: $lst[$i].id,
       log_source_id: $pe[$i].log_source_id,
       regex_property_identifier: $pe[$i].regex_property_identifier,
       property_type: $rp[$i].property_type,
       regex_name: $rp[$i].name,
       lst_name: $lst[$i].name,
       ls_name: $ls[$i].name
     }
  ]
'

Примечание: меня бы не слишком беспокоило, что - -argfile официально не рекомендуется, но если это вас беспокоит, есть много обходных путей, хотя некоторые из них зависят от версии. Если вам нужно нерекомендуемое решение, которое будет работать с любой версией jq, я бы использовал форму:

jq -s -f program.jq \ 
 log_source_types.json \
 log_sources.json \
 property_expressions.json \
 regex_properties.json

, где program.jq начинается с определения четырех $ -переменных, начиная с: .[0] as $lst |

...