使用 jq 根据键数组修改 JSON 值

Modify JSON values based on array of keys using jq

我需要使用 jq 更改 JSON 对象中一组键(在变量中定义)的值。

例如,我有这个 JSON 对象:

{
    foo: {
        bar: 1,
        baz: 2,
        qux: 3
    }
}

和以下变量:

update_keys = ["bar", "baz"]

我想说'change the value of the keys in update_keys to X'.

以下作品:

.foo = (.foo | 
        to_entries | 
        map(if .key == "bar" or .key == "baz" 
        then . + { "value":"X" } 
        else . 
        end) |
        from_entries)

但我正在寻找一种表达 if .key in update_keys 或类似逻辑的方式,而不是 if .key == "bar" or .key == "baz"

给你。

过滤器

.foo |= with_entries( .value = if ([.key] | inside(["bar", "baz"])) then "X" else .value end )

输入

{
    "foo": {
        "bar": 1,
        "baz": 2,
        "qux": 3
    }
}

输出

{
  "foo": {
    "bar": "X",
    "baz": "X",
    "qux": 3
  }
}

查看食谱以了解更多 jq 用法的食谱和技巧:
https://github.com/stedolan/jq/wiki/Cookbook

这里有一个稍微不同的方法,使用 --argjson 参数化 update_keys,和 index/1:

$ cat update.jq
.foo |= with_entries( . as $in 
          | if $update_keys | index($in.key) then .value = "X" else empty end)

$ update_keys='["bar", "baz"]'

$ jq --argjson update_keys "$update_keys" -f update.jq input.json

Output:

{
  "foo": {
    "bar": "X",
    "baz": "X"
  }
}

在这个问题中,因为 $update_keys 只是一个数组,所需要的只是

 .foo[ $update_keys[] ] = "X"

例如如果

  ["bar","baz"] as $update_keys
| .foo[ $update_keys[] ] = "X"

filter.jq 中,data.json 包含(稍微更正的)数据

{
  "foo": {
    "bar": 1,
    "baz": 2,
    "qux": 3
  }
}

然后

jq -M -f filter.jq data.json

产生

{
  "foo": {
    "bar": "X",
    "baz": "X",
    "qux": 3
  }
}

如果您想传递更新密钥的值而不是在脚本中定义它,您可以轻松地使用 --argjson,如 peak 的答案所示。