
假設我有一個如下所示的 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)'
,這將刪除keyA
json 中的所有鍵,但我想根據它們的值排除鍵...如何使用 排除所有具有值的"null"
鍵jq
?
答案1
del(..|select(. == "null"))
這使用了遞歸下降運算符..
和select
功能尋找物件中任何位置的所有位置,其值等於"null"
並將它們賦予del
。select
評估布林表達式來決定是否包含特定值,同時..
將樹中的每個值賦予它,並del
接受任何生成位置的表達式,這就是這樣做的。 (示範)
您可以使用該path
函數來檢查它發現了什麼:
path(..|select(. == "null"))
並調試它認為您要首先嘗試刪除的內容。這輸出是一個鍵數組,要遞歸地達到該值,因此數組中的最後一項是實際要刪除的鍵。
您也可以在 jq 1.6 及更高版本中使用更新分配|= empty
(在早期版本中它會默默地失敗)。您可能會或可能不會發現這一點更清楚(..|select(. == "null")) |= empty
:(示範) 刪除那些相同的鍵。
如果您的值是 true null
,而不是 string "null"
,您可以使用nulls
內建函數來取代整個select
: del(..|nulls)
。
如果您的值是 true null和你正在使用傑q 1.5(許多發行版中的當前版本),您需要使用 來recurse(.[]?; true)
代替..
.這是因為空值被明確排除在外..
(因為它被定義為recurse
, 哪個定義為 recurse(.[]?)
,其定義為recurse(.[]?; . != null)
)。不過,這種行為在 1.6 中改為上面的(更有用的)行為文件沒有改變,這似乎是個文檔錯誤。
答案2
假設您知道要測試第二級的值:
jq 'del(.[][] | select(. == "null"))' file
這會刪除從頂部開始的第二層上的每個鍵值對,其中值是文字 string null
。
鑑於問題中的文檔,這會產生預期的輸出。
使用高於 1.5 的版本jq
,您也可以將資料更新為沒有該null
值的位元:
jq '.[][] |= select(. != "null")' file