2013-09-24 62 views
9

我有一個由科學儀器創建的層級較深的JSON對象,因此該文件有點大(1.3MB),並且不易被人讀取。我想爲JSON對象獲取一個特定深度的鍵列表。例如,給定一個像這樣的輸入對象使用jq列出JSON對象中的鍵

{ 
    "acquisition_parameters": { 
     "laser": { 
      "wavelength": { 
       "value": 632, 
       "units": "nm" 
      } 
     }, 
     "date": "02/03/2525", 
     "camera": {} 
    }, 
    "software": { 
     "repo": "github.com/username/repo", 
     "commit": "a7642f", 
     "branch": "develop" 
    }, 
    "data": [{},{},{}] 
} 

我想要一個像這樣的輸出。

{ 
    "acquisition_parameters": [ 
     "laser", 
     "date", 
     "camera" 
    ], 
    "software": [ 
     "repo", 
     "commit", 
     "branch" 
    ] 
} 

這主要是爲了能夠枚舉JSON對象中的內容。在處理來自儀器的JSON對象開始發散之後:例如,有些可能有像.frame.cross_section.stats.fwhm這樣的字段,而另一些可能有.sample.species,所以能夠在命令行上查詢JSON對象會很方便。

回答

10

下應該做的正是你想要的

jq '[(keys - ["data"])[] as $key | { ($key): .[$key] | keys }] | add' 

這將給出以下輸出,使用你上述輸入:

{ 
    "acquisition_parameters": [ 
    "camera", 
    "date", 
    "laser" 
    ], 
    "software": [ 
    "branch", 
    "commit", 
    "repo" 
    ] 
} 
3

鑑於你的目的,你可以使用paths內置到列表中輸入的所有路徑有一個更容易的時間,然後在所需的深度截斷:

$ echo '{"a":{"b":{"c":{"d":true}}}}' | jq -c '[paths|.[0:2]]|unique' 
[["a"],["a","b"]] 
0

這裏是另一個變化uing 減少的setpath它假定你有一組特定的頂級鍵要檢查:

. as $v 
| reduce ("acquisition_parameters", "software") as $k (
    {}; setpath([$k]; $v[$k] | keys) 
)