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。更新されたキーは項目の1つから選択されます.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

これにより、と呼ばれる2つの内部jq変数が生成されます。たとえば、上記のように二重引用符を含めることができるように、値は正しくエンコードされます。$querykey$newval$newval

関連情報