Сравнить 2 массива json и вернуть разницу

У нас есть собственный CD Pipeline Tool, который, к сожалению, не контролирует параметры развертывания. Поэтому я помещаю их в репозиторий Bitbucket в виде файла json и проверяю их на соответствие REST API этого CD Tool.

Итак, у меня есть 2 массива json, которые структурно одинаковы, но могут содержать разные объекты или значения в этих объектах. Я хочу сравнить их, чтобы увидеть, если они разные и что отличается.

До сих пор я использовал решение отсюда: Использование jq или альтернативных инструментов командной строки для сравнения файлов JSON

Итак, я поместил это в свой код:

jq --argjson a "${bb_cfg}" --argjson b "${cd_tool_cfg}" -n 'def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); ($a | (post_recurse | arrays) |= sort) as $a | ($b | (post_recurse | arrays) |= sort) as $b | $a == $b'

теперь я получаю истину, если они идентичны, или ложь, если у 2 jsons есть различия, но я не знаю, чем они отличаются.

Я пытался сделать это с помощью этого, если я получу ложный ответ:

diff --suppress-common-lines -y <(jq . -S <<< "${bb_cfg}") <(jq . -S <<< "${cd_tool_cfg}")

Введите $bb_cfg:

[{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "true",
    "tags": []
},
{
    "key": "BB_CFG_REPO_NAME",
    "value": "cd-tool-cfg",
    "tags": []
}]

Введите $cd_tool_cfg

[{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "false",
    "tags": []
},
{
    "key": "BB_CFG_REPO_NAME",
    "value": "cd-tool-cfg",
    "tags": []
}]

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

    "value": "true"                       |     "value": "false"

поэтому я не получаю здесь весь объект json, чтобы быстро узнать, какой параметр отличается.

В конечном итоге я хочу получить что-то вроде этого:

{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "true",
    "tags": []
}
{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "false",
    "tags": []
}

где я могу сохранить это в переменной в моем сценарии bash и преобразовать в вывод, который я могу использовать.

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
6
0
1 227
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать вариант jq-c или --compact-output:

diff <(jq -c .[] <<<"$bb_cfg") <(jq -c .[] <<<"$cd_tool_cfg")
1c1
< {"key":"IGNORE_VALIDATION_ERROR","value":"true","tags":[]}
---
> {"key":"IGNORE_VALIDATION_ERROR","value":"false","tags":[]}

Опция -c просто выводит json с каждым элементом массива в отдельной строке.

Следующая команда даст вам то, что вы просили:

diff --old-line-format = "%L" --unchanged-line-format = "" --new-line-format = "%L" <(jq -c .[] <<<"$bb_cfg") <(jq -c .[] <<<"$cd_tool_cfg") | jq

выведет:

{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "true",
    "tags": []
}
{
    "key": "IGNORE_VALIDATION_ERROR",
    "value": "false",
    "tags": []
}

Другие вопросы по теме