递归合并 JSON 字符串与文件,使用 jq。

huangapple go评论73阅读模式
英文:

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: &quot;buzz&quot;`), 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 &#39;. * $in[0]&#39; &lt;&lt;&lt; &quot;$default&quot;
{
  &quot;admin&quot;: {
    &quot;enabled&quot;: true
  },
  &quot;horses&quot;: {
    &quot;count&quot;: 1,
    &quot;fizz&quot;: &quot;buzz&quot;,
    &quot;foo&quot;: &quot;bar&quot;
  }
}

Using kislyuk/yq:

yq --argfile in override.json &#39;. * $in&#39; &lt;&lt;&lt; &quot;$default&quot;
{
  &quot;horses&quot;: {
    &quot;count&quot;: 1,
    &quot;fizz&quot;: &quot;buzz&quot;,
    &quot;foo&quot;: &quot;bar&quot;
  },
  &quot;admin&quot;: {
    &quot;enabled&quot;: true
  }
}

Using mikefarah/yq:

yq -o json &#39;. * load(&quot;override.json&quot;)&#39; &lt;&lt;&lt; &quot;$default&quot;
{
  &quot;horses&quot;: {
    &quot;count&quot;: 1,
    &quot;fizz&quot;: &quot;buzz&quot;,
    &quot;foo&quot;: &quot;bar&quot;
  },
  &quot;admin&quot;: {
    &quot;enabled&quot;: true
  }
}

huangapple
  • 本文由 发表于 2023年2月24日 16:27:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554178.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定