Dung Pham
Dung Pham

Reputation: 39

Get unique nested JSON keys with JQ

How to get the unique keys from attributes key with JQ

{"id":1, "attributes":{"a": 1, "b": 2, "c": 3}}
{"id":2, "attributes":{"a": 4, "b": 5, "d": 6}}
{"id":3, "name":"ABC"}

Result like this [ "a", "b", "c", "d" ]

I'm try like this

jq '.attributes' test.json | jq -r '[inputs | keys[]] | unique | sort'

or

jq -r '[inputs.attributes | keys[]] | unique | sort' test.json

but getting error

jq: error (at :11): null (null) has no keys

Upvotes: 0

Views: 496

Answers (3)

knittl
knittl

Reputation: 265151

With slurp:

jq -s 'map(.attributes|keys?)|add|unique' test.json
  • -s loads the input file as array
  • map(.attributes|keys?) extracts only the keys (ignoring errors, such as trying to get keys of null)
  • add merges all nested arrays into a single array ([[1,2],[2,3]] becomes [1,2,2,3])
  • unique sorts and removes duplicates

Upvotes: 0

peak
peak

Reputation: 116690

Along the lines of your second attempt:

jq -n '[inputs.attributes // empty | keys_unsorted[]] | unique'

The important point is that we have to take care of the case where there is no "attributes" key.

Note also that unique sorts, so (unless you're using gojq) we can use keys_unsorted to avoid redundant sorting.

Upvotes: 0

pmf
pmf

Reputation: 36033

One way could be using reduce on subsequent inputs:

jq 'reduce inputs.attributes as $a (.attributes; . + $a) | keys'
[
  "a",
  "b",
  "c",
  "d"
]

Demo

Upvotes: 1

Related Questions