簡體   English   中英

使用JQ從JSON中選擇特定的,任意嵌套的對象

[英]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]

program.jq

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM