[英]Use JQ to select specific, arbitrarily nested objects from JSON
我正在尋找一種有效的方法來搜索大型JSON對象中與過濾器匹配的“子對象” select()
我想是通過select()
)。 但是,頂級JSON是一個對象,其中包含任意嵌套,包括更簡單的值,對象和對象數組。 例如:
{
"name": "foo",
"class": "system",
"description": "top-level-thing",
"configuration": {
"status": "normal",
"uuid": "id"
},
"children": [
{
"id": "c1",
"class": "c1",
"children": [
{
"id": "c1.1",
"class": "c1.1"
},
{
"id": "c1.1",
"class": "FINDME"
}
]
},
{
"id": "c2",
"class": "FINDME"
}
],
"thing": {
"id": "c3",
"class": "FINDME"
}
}
我有一個解決方案,它確實我想要的(並且是可以理解的) 部分 :
jq -r '.. | arrays | .[] | select(.class=="FINDME"?) | .id'
返回:
c2
c1.1
...但是,它錯過了c3
,而且它更改了項目輸出的順序。 另外,我希望它可以在可能非常大的JSON結構上運行,我想確保找到有效的解決方案。 對於jq
新手(仍包括我自己)仍然可讀的東西,加分。
FWIW,在幫助他人的過程中,我一直在使用這些幫助我的參考文獻:
這是流解析器解決方案。 要理解它,您需要閱讀--stream
選項,但關鍵是輸出包含以下形式的行:[PATH,VALUE]
foreach inputs as $in (null;
if has("id") and has("class") then null
else . as $x
| $in
| if length != 2 then null
elif .[0][-1] == "id" then ($x + {id: .[-1]})
elif .[0][-1] == "class"
and .[-1] == "FINDME" then ($x + {class: .[-1]})
else $x
end
end;
select(has("id") and has("class")) | .id )
jq -n --stream -f program.jq input.json
"c1.1"
"c2"
"c3"
對於小型到中等大小的JSON輸入,您使用..
處於正確的軌道,但似乎想要選擇objects
,如下所示:
.. | objects | select(.class=="FINDME"?) | .id
對於非常大的JSON文檔,這可能需要太多內存,因此可能值得了解jq的流解析器。 不幸的是,它很難使用,因此我建議嘗試上述方法,如果您有興趣,請在通常的位置查看有關--stream
選項的文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.