次の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