英文:
Recursive merge JSON string with file using jq
问题
我有一个名为default
的bash字符串,其中包含以下内容:
$ echo $default
{
"horses": {
"count": 0,
"fizz": "buzz"
},
"admin": {
"enabled": false
}
}
还有一个名为override.json
的文件,其中包含以下内容:
$ cat override.json
{
"horses": {
"count": 1,
"foo": "bar"
},
"admin": {
"enabled": true
}
}
我想要使用jq
递归合并它们,以产生以下结果:
{
"horses": {
"count": 1,
"foo": "bar",
"fizz": "buzz"
},
"admin": {
"enabled": true
}
}
我尝试过阅读文档并尝试了一些方法,比如:
jq -s '.[0] * .[1]' $(echo $default) override.json
但我的bash和流操作技能有限。
英文:
I have a bash string default
with content
$ echo $default
{
"horses": {
"count": 0,
"fizz": "buzz"
},
"admin": {
"enabled": false
}
}
and a file override.json
with content
$ cat override.json
{
"horses": {
"count": 1,
"foo": "bar"
},
"admin": {
"enabled": true
}
}
I want to recursively merge these using jq
to produce the result
{
"horses": {
"count": 1,
"foo": "bar",
"fizz": "buzz"
},
"admin": {
"enabled": true
}
}
I've tried to understand the docs and a few things like
jq -s '.[0] * .[1]' $(echo $default) override.json
but my bash and stream skills are limited.
答案1
得分: 2
顺便提一下,你的 `default` 变量几乎是一个有效的 jq 程序/过滤器(尽管不是有效的 JSON)。如果在 `fizz:buzz` 行中引用该值(更改为 `fizz: "buzz"`),那么你可以直接将其用作递归合并运算符的左操作数:
```bash
jq "$default * ." override.json
针对更新后的问题(其中 default
变量现在具有有效的 JSON),应该这样调用 jq:
jq --argjson defaults "$default" '$defaults * .' override.json
<details>
<summary>英文:</summary>
Incidentally, your `default` variable is _almost_ (!) valid jq program/filter (albeit not valid JSON). If you quote the value in the `fizz:buzz` line (change to `fizz: "buzz"`), then you could use it directly as the LHS of the recursive-merge operator:
jq "$default * ." override.json
*****
With the updated question (which now has valid JSON in the `default` variable), jq should be invoked as follows:
jq --argjson defaults "$default" '$defaults * .' override.json
</details>
# 答案2
**得分**: 1
[stedolan/jq](https://github.com/stedolan/jq) 可以很好地处理JSON内容。但是`$default`的内容不是有效的JSON(缺少字符串引号,与文件的内容进行比较,文件内容*是*有效的JSON)。
然而,变量的内容是有效的YAML(JSON的超集),因此可以使用YAML处理器。以下是一些选项:
#### 使用 [itchyny/gojq](https://github.com/itchyny/gojq):
```sh
gojq --yaml-input --slurpfile in override.json '. * $in[0]' <<< "$default"
{
"admin": {
"enabled": true
},
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
}
}
使用 kislyuk/yq:
yq --argfile in override.json '. * $in' <<< "$default"
{
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
},
"admin": {
"enabled": true
}
}
使用 mikefarah/yq:
yq -o json '. * load("override.json")' <<< "$default"
{
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
},
"admin": {
"enabled": true
}
}
英文:
stedolan/jq would be a good choice to process JSON content. But the content of $default
is not valid JSON (it lacks string quoting, coompare it to the file's content which is valid JSON).
However, the variable's content is valid YAML (a superset of JSON), so using a YAML-processor will work. Here are a few options:
Using itchyny/gojq:
gojq --yaml-input --slurpfile in override.json '. * $in[0]' <<< "$default"
{
"admin": {
"enabled": true
},
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
}
}
Using kislyuk/yq:
yq --argfile in override.json '. * $in' <<< "$default"
{
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
},
"admin": {
"enabled": true
}
}
Using mikefarah/yq:
yq -o json '. * load("override.json")' <<< "$default"
{
"horses": {
"count": 1,
"fizz": "buzz",
"foo": "bar"
},
"admin": {
"enabled": true
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论