【问题标题】:jq - create a new object from the diff in key values of two JSON filesjq - 根据两个 JSON 文件的键值的差异创建一个新对象
【发布时间】:2020-10-04 18:01:49
【问题描述】:

如果存在来自两个不同的JSON 文件的每个键的值差异,如何创建一个JSON 对象?

这将是一篇很长的文章,但主要是由于我使用的 JSON 文件。请多多包涵。

我有一个源文件 - original.json

{
  "billLogAnalyticsAsDavisDataUnits": false,
  "billingProvider": "INTERNAL",
  "blockUIDate": 1652572799000,
  "chatEnabled": false,
  "customMetricsLimit": 9223372036854776000,
  "customMetricsOverageLimit": 9223372036854776000,
  "davisDataUnitsAnnualLimit": -1,
  "davisDataUnitsEnabled": false,
  "davisDataUnitsMigrated": false,
  "davisDataUnitsMonthlyLimit": -1,
  "demUnitsAnnualQuota": 0,
  "demUnitsQuota": 0,
  "expirationCounterEnabled": true,
  "expirationTime": 1652572799000,
  "externalApiQuota": 2147483647,
  "hostUnitsCapping": {
    "fullstackHostLimit": 0,
    "hasContainersHostLimit": 0,
    "hostUnitsCappingEnabled": false,
    "infrastructureOnlyHostLimit": 0
  },
  "hostUnitsQuota": 2147483647,
  "ibmSystemZCICSIMSMonitoring": false,
  "infrastructureSupportedTechnologies": {
    "infrastructureOnlySupport": true,
    "logAgent": true,
    "maxInfrastructureOnlyAgents": 9223372036854776000,
    "networkAgent": true,
    "pluginAgent": true
  },
  "iotEntityQuota": 20,
  "iotTsQuota": 10,
  "isConsumption": false,
  "isCreditExhausted": false,
  "isRumEnabled": false,
  "licenseType": "PAYING",
  "logAnalyticsIngressQuota": 9223372036854776000,
  "logAnalyticsIngressQuotaAnnually": 9223372036854776000,
  "logAnalyticsStorageEnabled": false,
  "logAnalyticsStorageQuota": 0,
  "maxActionsPerMinute": 3500,
  "maxAgents": 2147483647,
  "maxHostUnitsQuota": -1,
  "maxPaasAgents": 2147483647,
  "maxWebChecks": 9223372036854776000,
  "maxWebChecksAnnual": 9223372036854776000,
  "overageCustomMetrics": true,
  "overageEnabled": false,
  "replayStorageDomQuotaInMb": 10000,
  "replayStorageDomRetention": 86400000,
  "retentionCode": 864000000,
  "retentionRum": 864000000,
  "retentionService": 1209600000,
  "retentionWebcheck": 864000000,
  "rumAdditionalUserPropertiesEnabled": true,
  "rumAdditionalUserPropertiesLowerLimit": 20,
  "sessionReplayEnabled": false,
  "sessionStorageQuota": 2147483647,
  "suspensionType": "NONE",
  "symbolicationFileStorageQuota": 1024,
  "syntheticEnabled": false,
  "useHostUnitWeighting": false,
  "visitsAnnualQuota": -1,
  "visitsQuota": -1
}

我需要替换一些存储在 template.json 文件中的具有新值的键

{
    "billLogAnalyticsAsDavisDataUnits": false,
    "billingProvider": "INTERNAL",
    "blockUIDate": 1652572799000,
    "chatEnabled": false,
    "demUnitsAnnualQuota": -1,
    "demUnitsQuota": -1,
    "isRumEnabled": false,
    "licenseType": "PAYING",
    "logAnalyticsIngressQuota": -1,
    "logAnalyticsIngressQuotaAnnually": -1,
    "logAnalyticsStorageEnabled": false,
    "logAnalyticsStorageQuota": 0,
    "overageCustomMetrics": true,
    "overageEnabled": false,
    "replayStorageDomQuotaInMb": 10000,
    "replayStorageDomRetention": 86400000,
    "retentionCode": 864000000,
    "retentionRum": 864000000,
    "retentionService": 1209600000,
    "retentionWebcheck": 864000000,
    "rumAdditionalUserPropertiesEnabled": true,
    "rumAdditionalUserPropertiesLowerLimit": 20,
    "sessionReplayEnabled": false,
    "sessionStorageQuota": 102400,
    "suspensionType": "NONE",
    "symbolicationFileStorageQuota": 1024,
    "syntheticEnabled": true,
    "useHostUnitWeighting": false,
    "visitsAnnualQuota": 0,
    "visitsQuota": -1
}

我正在使用 jq 的以下调用

jq -n --argfile original.json --argfile template template.json '$original |$original +=$template' >updated.json

获取具有更新值的新 updated.json 文件,然后将其提交到 API 服务器。

API 服务器在处理后发出一个具有完全相同结构的新文件。但是,某些关键值可能会发生变化。这是从 API 服务器下载的文件 - downloaded.json

{
  "billLogAnalyticsAsDavisDataUnits": false,
  "billingProvider": "INTERNAL",
  "blockUIDate": 1652572799000,
  "chatEnabled": false,
  "customMetricsLimit": 9223372036854776000,
  "customMetricsOverageLimit": 9223372036854776000,
  "davisDataUnitsAnnualLimit": -1,
  "davisDataUnitsEnabled": true,
  "davisDataUnitsMigrated": false,
  "davisDataUnitsMonthlyLimit": -1,
  "demUnitsAnnualQuota": -1,
  "demUnitsQuota": -1,
  "expirationCounterEnabled": true,
  "expirationTime": 0,
  "externalApiQuota": 2147483647,
  "hostUnitsCapping": {
    "fullstackHostLimit": 0,
    "hasContainersHostLimit": 0,
    "hostUnitsCappingEnabled": false,
    "infrastructureOnlyHostLimit": 0
  },
  "hostUnitsQuota": -1,
  "ibmSystemZCICSIMSMonitoring": false,
  "infrastructureSupportedTechnologies": {
    "infrastructureOnlySupport": true,
    "logAgent": true,
    "maxInfrastructureOnlyAgents": 9223372036854776000,
    "networkAgent": true,
    "pluginAgent": true
  },
  "iotEntityQuota": 20,
  "iotTsQuota": 10,
  "isConsumption": false,
  "isCreditExhausted": false,
  "isRumEnabled": true,
  "licenseType": "PAYING",
  "logAnalyticsIngressQuota": -1,
  "logAnalyticsIngressQuotaAnnually": -1,
  "logAnalyticsStorageEnabled": false,
  "logAnalyticsStorageQuota": 0,
  "maxActionsPerMinute": 3500,
  "maxAgents": 2147483647,
  "maxHostUnitsQuota": -1,
  "maxPaasAgents": 2147483647,
  "maxWebChecks": 9223372036854776000,
  "maxWebChecksAnnual": 9223372036854776000,
  "overageCustomMetrics": true,
  "overageEnabled": false,
  "replayStorageDomQuotaInMb": 10000,
  "replayStorageDomRetention": 86400000,
  "retentionCode": 864000000,
  "retentionRum": 864000000,
  "retentionService": 1209600000,
  "retentionWebcheck": 864000000,
  "rumAdditionalUserPropertiesEnabled": true,
  "rumAdditionalUserPropertiesLowerLimit": 20,
  "sessionReplayEnabled": false,
  "sessionStorageQuota": 102400,
  "suspensionType": "NONE",
  "symbolicationFileStorageQuota": 1024,
  "syntheticEnabled": true,
  "useHostUnitWeighting": false,
  "visitsAnnualQuota": 0,
  "visitsQuota": -1
}

这是我的任务 - 我需要找出 updated.jsondownloaded.json

之间的区别

我正在使用差异

diff <(jq -S . update.json) <(jq -S . downloaded.json)

它产生以下结果

<   "davisDataUnitsEnabled": false,
---
>   "davisDataUnitsEnabled": true,
15c15
<   "expirationTime": 1652572799000,
---
>   "expirationTime": 0,
23c23
<   "hostUnitsQuota": 2147483647,
---
>   "hostUnitsQuota": -1,
36c36
<   "isRumEnabled": false,
---
>   "isRumEnabled": true,

我想要的是 - 使用原始(来自 updated.json)和新(来自下载的.json)文件创建一个新对象,因此它应该如下所示:

    "Original": {
        "davisDataUnitsEnabled": false,
        "expirationTime": 1652572799000,
        "hostUnitsQuota": 2147483647,
        "isRumEnabled": false
    },
    "Updated": {
        "davisDataUnitsEnabled": true,
        "expirationTime": 0,
        "hostUnitsQuota": -1,
        "isRumEnabled": true
    }
}

我尝试使用to_entriesfrom_entries查看更新和下载之间的区别,将以下jq命令组合在一起:

jq -n \
--argfile original original.json \
--argfile download downloaded.json \
--argfile template template.json \
'$original |$original +=$template | 
($original | to_entries) as $x | 
($download | to_entries) as $y | 
$y - $x | from_entries'

但是,输出与 diff 相比有很大不同:

{
  "davisDataUnitsEnabled": true,
  "demUnitsAnnualQuota": -1,
  "demUnitsQuota": -1,
  "expirationTime": 0,
  "hostUnitsQuota": -1,
  "isRumEnabled": true,
  "logAnalyticsIngressQuota": -1,
  "logAnalyticsIngressQuotaAnnually": -1,
  "sessionStorageQuota": 102400,
  "syntheticEnabled": true,
  "visitsAnnualQuota": 0
}

以上输出中列出了另外七个键,而不是来自 diff 的四个,这七个键在 updated.jsondownloaded.json 中具有完全相同的值

我的问题 - 是什么导致这七个附加键出现在 jq 输出中? 我可以使用 jq 获得值不同的键的正确输出,并按照我想要的方式格式化输出吗?

-- 附:经过一番挖掘,发现comm 给了我想要的输出

comm --nocheck-order -13 <(jq -S . updated.json) <(jq -S . downloaded.json)

产生输出:

  "davisDataUnitsEnabled": true,
  "expirationTime": 0,
  "hostUnitsQuota": -1,
  "isRumEnabled": true,

现在,如果我可以通过JQ 将该输出放在"Updated" 对象下,同时忽略尾随逗号,那可能就是最终结果...

更新我找出了问题所在,并在下面写了答案。保留问题,因为有人可能会遇到相同的情况。

【问题讨论】:

    标签: json comparison diff jq


    【解决方案1】:

    仅在发布问题并重新检查以下jq 命令后,我才发布说我没有将组合的原始文件和模板文件保存在变量中,因此将原始的未修改文件分配给 var @987654322 @。

    jq -n \
    --argfile original original.json \
    --argfile download downloaded.json \
    --argfile template template.json \
    '$original |$original +=$template | 
    ($original | to_entries) as $x | 
    ($download | to_entries) as $y | 
    $y - $x | from_entries
    

    相反,产生我想要的结果的正确jq 命令如下:

    `jq` -n \
    --argfile original original.json \
    --argfile download downloaded.json \
    --argfile template template.json \
    '$original |($original +=$template | to_entries) as $x |
    ($download | to_entries) as $y | 
    ($y - $x | from_entries) as $new |
    ($x - $y | from_entries) as $old |
    | [{"Original":$old,"Updated": $new}]'
    

    产生正确的输出:

    [
      {
        "Original": {
          "davisDataUnitsEnabled": false,
          "expirationTime": 1652572799000,
          "hostUnitsQuota": 2147483647,
          "isRumEnabled": false
        },
        "Updated": {
          "davisDataUnitsEnabled": true,
          "expirationTime": 0,
          "hostUnitsQuota": -1,
          "isRumEnabled": true
        }
      }
    ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 2020-06-07
      相关资源
      最近更新 更多