
次のような JSON ファイルがあるとします。
[
{
"name1": "fruits",
"name2": "cars",
"name3": "houses"
}
]
jq
次のように値の名前を変更するために使用できることがわかっています。
jq '[.[] | .["newname1"] = .name1 | del(.name1)]' file
これはうまく機能し、より複雑な JSON 構造でも変更を加えることができます...ただし、これは変更したいキーの非常に明示的な宣言です。同じことを実行する別の方法は、次のコマンドを使用することです。
jq 'map(with_entries(if .key == "name1" then .key = "newname1" else . end))' file
これは、オブジェクトの配列である JSON 内の特定の名前を持つすべてのキーをチェックし、それらを変更する方法です。key
この場合、名前を明示的に宣言する必要はありません。ただし、これはオブジェクトの配列でのみ機能します。そのような JSON 内のすべてのキーを再帰的に変更する方法を見つけたいと思います。次のような JSON があるとします。
{
"name1": "one",
"type": "FeatureCollection",
"features": [
{
"name1": "one",
"valueA": "0",
"valueB": "0",
"keyB": "2",
"keyC": "3"
},
{
"name1": "two",
"valueA": "11",
"valueB": "21",
"keyB": "15",
"keyC": "20"
}
]
}
最後のjq
コマンドはこの JSON では機能しません。name1
を使用してすべてのキーを再帰的に変更する方法はありますかjq
? おそらく、このコマンドと一緒に使用する方法を見つけるでしょうかrecurse(.[]?;true)
? それは可能ですか?
答え1
jq 'walk(if type == "object" then with_entries( if .key == "name1" then .key = "newname1" else . end ) else . end)' file
jq
これは、マニュアル (walk()
関数を説明するセクション)からほぼそのまま引用したものです。walk()
関数は「再帰的map()
」に動作し、注意する必要があるのは、現在処理しているエンティティのタイプを確認することだけです。
を使用するとwalk()
、最初のアプローチを適用することもできます。
jq 'walk(if type == "object" and has("name1") then ( .newname1 = .name1 | del(.name1) ) else . end)' file
ただし、これにより、キーが見つかった位置でnewname1
置き換えられるのではなく (これが重要であれば)、各オブジェクトの最後にキーが配置されます。name1
別のアプローチ ( jq
1.6 を使用) は、再帰的な下降演算子を使用して..
、探しているキーを持つものをすべて選択し、それらのオブジェクトを更新することです。
jq '(.. | select(has("name1")?)) |= with_entries(if .key == "name1" then .key = "newname1" else . end)' file