使用 jq 更新包含具有特定值的其他属性的对象的属性

使用 jq 更新包含具有特定值的其他属性的对象的属性

使用 jq,是否可以更新在某些其他属性中包含特定值的对象的属性值?

在下面的示例中,我想设置所有具有“keyname”=“foo”的对象的“value”属性的值。

示例 .json 文件如下所示:

"root" : {
  "instances": [
    {
      "name": "1",
      "configs": [
        {
          "keyname": "foo",
          "value": "" // <- update/set this
        },
        {
          "keyname": "barrr",
          "value": "barrrr"
        }
      ]
    },
    {
      "name": "2",
      "configs": [
        {
          "keyname": "foo",
          "value": "" // <- update/set this
        },
        {
          "keyname": "buzzz",
          "value": "buzzz"
        }
      ]
    }
  ]
}

我尝试了这个,但没有成功,我收到一个关于数组不是字符串的错误:

jq '(.root.instances.configs[] | select(.keyname==foo)).value = foo'

答案1

假设您的 JSON 文档格式良好,但您显示的示例并非如此,因为它包含多个问题:

$ cat file
{
  "root": {
    "instances": [
      {
        "name": "1",
        "configs": [
          {
            "keyname": "foo",
            "value": ""
          },
          {
            "keyname": "barrr",
            "value": "barrrr"
          }
        ]
      },
      {
        "name": "2",
        "configs": [
          {
            "keyname": "foo",
            "value": ""
          },
          {
            "keyname": "buzzz",
            "value": "buzzz"
          }
        ]
      }
    ]
  }
}
$ jq '( .root.instances[].configs[] | select(.keyname == "foo") ).value |= "foo"' file
{
  "root": {
    "instances": [
      {
        "name": "1",
        "configs": [
          {
            "keyname": "foo",
            "value": "foo"
          },
          {
            "keyname": "barrr",
            "value": "barrrr"
          }
        ]
      },
      {
        "name": "2",
        "configs": [
          {
            "keyname": "foo",
            "value": "foo"
          },
          {
            "keyname": "buzzz",
            "value": "buzzz"
          }
        ]
      }
    ]
  }
}

jq表达式将键的值更新.value为字符串foo。更新的密钥是从 中的条目之一中选择的.root.instances[].configs[]。请注意,这 .root.instances是一个数组,并且.configs其每个元素中的每个条目也是一个数组。该语句使用字符串select()测试密钥。.keynamefoo

制作查询键和新值变量的过程如下:

jq  --arg querykey 'foo' \
    --arg newval 'The train said "choo choo"' \
    '( .root.instances[].configs[] | select(.keyname == $querykey) ).value |= $newval' file

这将创建两个名为和 的内部jq变量。它们的值将被正确编码,以便例如可以包含双引号,如上所示。$querykey$newval$newval

相关内容