jq - 根据两个 JSON 文件的键值差异创建一个新对象
jq - create a new object from the diff in key values of two JSON files
如果来自两个不同的 JSON
文件,如何创建一个显示每个键值差异的 JSON
对象?
这会很长 post,但主要是因为我正在使用 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[ 之间的区别=32=]
我正在使用 diff
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)和新文件(来自 downloaded.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 获得具有不同值的键的正确输出,并按照我想要的方式格式化输出吗?
--
P.S。经过一番挖掘,发现 comm
给了我想要的输出
comm --nocheck-order -13 <(jq -S . updated.json) <(jq -S . downloaded.json)
产生输出:
"davisDataUnitsEnabled": true,
"expirationTime": 0,
"hostUnitsQuota": -1,
"isRumEnabled": true,
现在,如果我可以通过 JQ
将该输出放在 "Updated"
对象下,同时忽略尾随逗号,那可能就是最终结果...
UPDATE 我弄清楚了问题所在并在下面写下了答案。保留问题原样,因为有人可能会遇到同样的情况。
仅在发布问题和 re-checking 以下 jq
命令后,我才宣布我没有将组合的原始文件和模板文件保存在变量中,因此原始的、未修改的文件是分配给 var $x
.
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
}
}
]
如果来自两个不同的 JSON
文件,如何创建一个显示每个键值差异的 JSON
对象?
这会很长 post,但主要是因为我正在使用 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[ 之间的区别=32=]
我正在使用 diff
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)和新文件(来自 downloaded.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 获得具有不同值的键的正确输出,并按照我想要的方式格式化输出吗?
--
P.S。经过一番挖掘,发现 comm
给了我想要的输出
comm --nocheck-order -13 <(jq -S . updated.json) <(jq -S . downloaded.json)
产生输出:
"davisDataUnitsEnabled": true,
"expirationTime": 0,
"hostUnitsQuota": -1,
"isRumEnabled": true,
现在,如果我可以通过 JQ
将该输出放在 "Updated"
对象下,同时忽略尾随逗号,那可能就是最终结果...
UPDATE 我弄清楚了问题所在并在下面写下了答案。保留问题原样,因为有人可能会遇到同样的情况。
仅在发布问题和 re-checking 以下 jq
命令后,我才宣布我没有将组合的原始文件和模板文件保存在变量中,因此原始的、未修改的文件是分配给 var $x
.
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
}
}
]