我已经阅读了几乎所有可以在SO上找到的问题,并且有相同的一般前提,而且我已经接近了三次不同的时间,但我无法做到这一点。
给定一个名为parameters.json
的JSON文件,其密钥对如此; (缩短为分享目的)
[
{
"ParameterKey": "Foo1",
"ParameterValue": "Bar1"
},
{
"ParameterKey": "Foo2",
"ParameterValue": "Bar2"
}
]
我想添加另一个密钥对,比如说
{
"ParameterKey": "Foo3",
"ParameterValue": "Bar3"
}
所以我最终得到了像
这样的文件[
{
"ParameterKey": "Foo1",
"ParameterValue": "Bar1"
},
{
"ParameterKey": "Foo2",
"ParameterValue": "Bar2"
},
{
"ParameterKey": "Foo3",
"ParameterValue": "Bar3"
}
]
我正在编写一个复制和更新AWS参数文件的bash脚本 - 这是密钥对的来源。我们有一个新的密钥对,需要在复制后添加到任何现有文件中。我可以得到if / then然后做得很好,它实际上添加了新的密钥对,这让我很难过。
随着大量的谷歌搜索,我最终得到了这个笨重的解决方法,我不太了解,虽然它生成了密钥对,但是没有将它添加回参数.json
item='{"ParameterKey": "RTSMSnapshotID"}'
jq --argjson item "$item" '$item + {"ParameterValue": ""}' parameters.json
我在命令行上正确地将密钥对打印回来,所以我想添加| sponge parameters.json
,但这会给我一个空文件。
我还考虑了一个sed解决方法,它修剪了文件的最后一行,然后添加了新的密钥对(和EOF),但当然sed并没有很好地使用换行符,我无法得到它工作。
我对使用bash中的任何内容以及jq中的任何内容的解决方案持开放态度。我仍然是bash / jq noob,所以我们非常感谢您的详细解释。
答案 0 :(得分:2)
使用argjson
的想法是正确的,但语法如下jq-1.5
jq --argjson obj '{ "ParameterKey": "Foo3", "ParameterValue": "Bar3" }' '. + [$obj]' < json
[
{
"ParameterKey": "Foo1",
"ParameterValue": "Bar1"
},
{
"ParameterKey": "Foo2",
"ParameterValue": "Bar2"
},
{
"ParameterKey": "Foo3",
"ParameterValue": "Bar3"
}
]
查看jq-documentation,了解有关+
和+=
运营商的详情。
我不知道如何在jq
本身中执行此操作,但您可以使用简洁的bash
技巧来执行此操作,
jq --argjson obj '{ "ParameterKey": "Foo3", "ParameterValue": "Bar3" }' '. + [$obj]' < json > temp && mv temp json
答案 1 :(得分:1)
如果你有一个带有JSON数组的文件(比如parameters.json),以及一个或多个带有JSON实体的附加文件(比如文件* .json),你想要在第一个文件中追加到数组,如果你想覆盖第一个文件,这是一个相当狡猾的解决方案,但需要jq 1.5或更高版本:
$ jq 'reduce inputs as $in (.; . + [$in])' parameters.json file*.json |
sponge parameters.json
请注意,使用此方法,每个辅助文件中的每个顶级JSON实体将分别附加到数组中。
使这有点狡猾的原因是inputs
在没有-n选项的情况下使用。
由于您提到bash
,请注意,如果任何“file * .json”来源是一个过程,您可以使用<( ... )
而不是指定文件名,例如:
$ jq 'reduce inputs as $in (.; . + [$in])' parameters.json <(curl -Ss ...) |
sponge parameters.json
如果您没有sponge
,那么您可以使用这个成语:
jq ..... > OUT && mv IN OUT