сравните 2 массива JSON и верните разницу - PullRequest
5 голосов
/ 10 апреля 2019

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

Итак, у меня есть 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 и преобразовать это в вывод, который я могу использовать.

1 Ответ

3 голосов
/ 10 апреля 2019

Вы можете использовать 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": []
}
...