The jq tutorial demonstrates simple filtering and rearranging of JSON data, but lacks any examples of how you might combine jq's more interesting features. So I thought it would be worth writing this up.
I want a list of which zones are in which views in my DNS server. I can get this information from BIND's statistics channel, with a bit of processing.
It's quite easy to get a list of zones, but the zone objects returned from the statistics channel do not include the zone's view.
$ curl -Ssf http://[::1]:8053/json | jq '.views[].zones[].name' | head -2 "authors.bind" "hostname.bind"
The view names are keys of an object further up the hierarchy.
$ curl -Ssf http://[::1]:8053/json | jq '.views | keys' [ "_bind", "auth", "rec" ]
I need to get hold of the view names so I can use them when processing the zone objects.
The first trick is to_entries which turns the "views" object into an array of name/contents pairs.
$ curl -Ssf http://[::1]:8053/json | jq -C '.views ' | head -6 { "_bind": { "zones": [ { "name": "authors.bind", "class": "CH", $ curl -Ssf http://[::1]:8053/json | jq -C '.views | to_entries ' | head -8 [ { "key": "_bind", "value": { "zones": [ { "name": "authors.bind", "class": "CH",
The second trick is to save the view name in a variable before descending into the zone objects.
$ curl -Ssf http://[::1]:8053/json | jq -C '.views | to_entries | .[] | .key as $view | .value' | head -5 { "zones": [ { "name": "authors.bind", "class": "CH",
I can then use string interpolation to print the information in the format I want. (And use array indexes to prune the output so it isn't ridiculously long!)
$ curl -Ssf http://[::1]:8053/json | jq -r '.views | to_entries | .[] | .key as $view | .value.zones[0,1] | "\(.name) \(.class) \($view)"' authors.bind CH _bind hostname.bind CH _bind dotat.at IN auth fanf2.ucam.org IN auth EMPTY.AS112.ARPA IN rec 0.IN-ADDR.ARPA IN rec
And that's it!