
次のような JSON があるとします。
{
"key1": {
"keyA": "1",
"keyB": "null",
"keyC": "null"
},
"key2": {
"keyA": "null",
"keyB": "3",
"keyC": "null"
}
}
null
JSON の値を持つすべてのキーを除外する方法を見つけたいと思います。結果は次のようになります。
{
"key1": {
"keyA": "1"
},
"key2": {
"keyB": "3"
}
}
jq
たとえば、を使用して特定のキーを名前で除外できることはわかっていますが、cat myjson.json | jq 'del(.[]|.keyA)'
これにより json 内のすべてのキーが消去されますが、値に応じてキーを除外したいのです...を使用してkeyA
値を持つすべてのキーを除外するにはどうすればよいですか?"null"
jq
答え1
del(..|select(. == "null"))
これは、再帰下降演算子..
そしてselect
関数は、オブジェクト内の任意の場所で に等しい値を持つすべての場所を検索し"null"
、 に渡しますdel
。select
はブール式を評価して特定の値を含めるかどうかを決定し、 は..
ツリー内のすべての値をそれに渡し、del
場所を生成する任意の式を受け入れます。これはこれを実行します。(デモ)
関数を使用してpath
、何が見つかったかを確認できます。
path(..|select(. == "null"))
まず何を削除しようとしているのかデバッグします。出力値に到達するために再帰的にたどるキーの配列であり、配列の最後の項目が実際に削除されるキーになります。
jq 1.6 以降では update-assignment も使用できます|= empty
(以前のバージョンでは何も表示されずに失敗します)。これはより明確になるかもしれませんし、そうでないかもしれません: (..|select(. == "null")) |= empty
(デモ) は同じキーを削除します。
値がnull
文字列ではなく true である場合は、全体の代わりに組み込み関数を使用"null"
できます。nulls
select
del(..|nulls)
値が真のヌルの場合そして使用しているjq 1.5(多くのディストリビューションの現在のバージョン)では、recurse(.[]?; true)
の代わりにを使用する必要があります..
。これは、null値が明示的に除外されるためです..
(それは次のように定義されますrecurse
、 どれのと定義されている recurse(.[]?)
(これは と定義されますrecurse(.[]?; . != null)
)。この動作は1.6で上記の(より便利な)動作に変更されましたが、ドキュメント変わっていない、それはドキュメントのバグのようです。
答え2
2 番目のレベルで値をテストする必要があると仮定します。
jq 'del(.[][] | select(. == "null"))' file
これにより、上から 2 番目のレベルにある、値がリテラル文字列であるすべてのキーと値のペアが削除されますnull
。
質問内のドキュメントが与えられれば、期待通りの出力が生成されます。
1.5 より新しいバージョンを使用するとjq
、値を持たないビットにデータを更新することもできますnull
。
jq '.[][] |= select(. != "null")' file