2013-09-24 8 views
9

Ho un oggetto JSON gerarchicamente profondo creato da uno strumento scientifico, quindi il file è piuttosto grande (1,3 MB) e non facilmente leggibile dalle persone. Mi piacerebbe avere un elenco di chiavi, fino ad una certa profondità, per l'oggetto JSON. Ad esempio, dato un oggetto di input come questoUso di jq per elencare le chiavi in ​​un oggetto 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": [{},{},{}] 
} 

Vorrei un'uscita come tale.

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

Questo è principalmente allo scopo di essere in grado di enumerare ciò che è in un oggetto JSON. Dopo l'elaborazione, gli oggetti JSON dallo strumento iniziano a divergere: ad esempio, alcuni potrebbero avere un campo come .frame.cross_section.stats.fwhm, mentre altri potrebbero avere .sample.species, quindi sarebbe opportuno poter interrogare l'oggetto JSON sulla riga di comando.

risposta

10

Il seguente dovrebbe fare esattamente quello che vuoi

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

Questo darà il seguente output, utilizzando l'ingresso che hai descritto sopra:

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

Dato il vostro scopo si potrebbe avere un tempo più facile utilizzando il paths integrato per elencare tutti i percorsi di ingresso e poi tronca alla profondità desiderata:

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

Ecco un'altra variazione uing ridurre e SetPath che presuppone una specifica serie di chiavi di primo livello si desidera esaminare:

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