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()
キーをテストします。.keyname
foo
クエリキーと新しい値変数を作成するプロセスは次のとおりです。
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