比较2个json数组并返回差

时间:2019-04-10 06:30:15

标签: json bash jq

我们有一个自定义的CD管道工具,很遗憾,该工具不会对部署参数进行版本控制。因此,我将它们作为json文件放入Bitbucket存储库中,并根据此CD工具的REST API对其进行了验证。

所以我有2个json数组,它们在结构上是相同的,但是可能包含不同的对象或这些对象中的值。我想对它们进行比较,看看它们是否不同以及有什么不同。

到目前为止,我从这里使用了解决方案: Using jq or alternative command line tools to diff JSON files

因此,我已将其放入我的代码中:

.main{
  margin-top: 32px;
  margin-left: 32px;
  display: flex;
  flex-direction: row;
  justify-content: left;
  align-items: center;
}
.line{
  height: 2px;
  min-width: 32px;
  border-bottom: 2px solid;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
}
 .line-name{
   margin: -20px 16px 0;
 }
.station{
  height: 8px;
  width: 8px;
  border-radius: 50%;
  border: 1px solid #000;
  display: flex;
  justify-content: center;
  align-items: center;
}
.station-name {
  margin: 0 16px -20px;
  white-space: nowrap;
}

现在,如果它们相同,则为true;如果2个json有差异,则为false,但是我不知道有什么不同。

如果我得到了错误的回复,我试图这样做:

<div class="main">
 <div class="station">
  <span class="station-name">first station</span>
 </div>
 <div class="line">
  <span class="line-name">short line</span>
 </div>
 <div class="station">
  <span class="station-name">loooooong station name</span>
 </div>
 <div class="line">
  <span class="line-name">very very very very loooooooong line name</span>
 </div>
 <div class="station">
  <span class="station-name">this on name</span>
 </div>
</div>

输入$ bb_cfg:

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'

输入$ cd_tool_cfg

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

之所以起作用,是因为如果只有不同的值,则输出将如下所示:

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

所以我不能在这里得到整个json对象,以快速找出哪些参数是不同的。

我最终想要得到的是这样的东西:

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

我可以将其存储在bash脚本中的变量中,并在可以使用的输出中进行转换。

1 个答案:

答案 0 :(得分:3)

您可以使用jq的{​​{1}}或-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":[]} 选项将简单地将每个数组成员的json输出在单独的行上。

以下命令将为您提供所需的内容:

-c

将输出:

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