【发布时间】: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.json 和 downloaded.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_entries和from_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.json 和 downloaded.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