A couple of quick and easy ways to display JSON data on the Linux command line

I interact with RESTful services daily and periodically need to review the JSON objects exposed through one or more endpoints. There are several Linux utilities that can take a JSON object and print the object in an easily readable form. The pygmentize utility (available in the python-pygments package) can be fed a JSON object via a file or STDIN:

$ curl http://bind:8080/json 2>/dev/null | pygmentize |more
{
  "json-stats-version":"1.2",
  "boot-time":"2017-09-09T11:56:04.442Z",
  "config-time":"2017-09-09T11:56:04.520Z",
  "current-time":"2017-09-09T12:10:36.054Z",
  "version":"9.11.2",
  .....
}

In the output above I’m retrieving a JSON object from the Bind statistics server and feeding it to pygmentize via STDIN. Pygmentize will take the object is given and produce a nightly formatted JSON object on STDOUT.

Pygmentize is super handy but the real power house of the JSON command line processors is jq. This amazing utility has numerous features which allow you to retrieve keys, values, objects and arrays and apply complex filters and operations to these elements. In its simplest form jq will take a JSON object and produce pretty output:

$ curl http://bind:8080/json 2>/dev/null | jq '.' |more
{
  "json-stats-version": "1.2",
  "boot-time": "2017-09-09T11:56:04.442Z",
  "config-time": "2017-09-09T11:56:04.520Z",
  "current-time": "2017-09-09T12:24:43.982Z",
  "version": "9.11.2",
  .....
}

To see the real power of jq we need to observe how to use operations and filters on a JSON object. The Bind statistics server produces a JSON object similar to the following (this was heavily edited to conserve space):

{
  "json-stats-version":"1.2",
  "boot-time":"2017-09-09T11:56:04.442Z",
  "config-time":"2017-09-09T11:56:04.520Z",
  "current-time":"2017-09-09T13:40:59.901Z",
  "version":"9.11.2",
  "codes":{
    "NOERROR":7798,
    "FORMERR":0,
    "SERVFAIL":2,
    "NXDOMAIN":166,
    "NOTIMP":0,
    "REFUSED":161,
    "YXDOMAIN":0,
    "YXRRSET":0,
    "NXRRSET":0,
    "NOTAUTH":0,
    "NOTZONE":0,
  },
  "qtypes":{
    "A":7023,
    "NS", 1,
    "PTR":153,
    "MX":1,
    "AAAA":950
  },
  .....
}

Lets say you wanted to view the number of A, NX, PTR and MX records queried. We can use the jq filter to grab the qtypes object and pass that through a filter to retrieve the values of the A, NS, PTR and MX keys:

$ curl http://bind:8080/json 2>/dev/null \
          | jq -r '.qtypes| "\(.A) \(.NS) \(.PTR) \(.MX)"'
7023 1 153 1

In this example I am using string interpolation to turn the values of A, NS, PTR and MX into a string which is then printed on STDOUT. Jq also has a number of useful math operations which can be applied to the values in a JSON object. To sum the totals of the various failure response codes in the rcodes object we can use the addition operation:

$ curl http://192.168.1.2:8080/json 2>/dev/null \
          | jq -r '.rcodes| .NXDOMAIN + .SERVFAIL \
                  + .REFUSED + .FORMERR'
8135

IN this example I am retrieving the values of the NXDOMAIN, SERVFAIL, REFUSED and FORMERR keys and sum’ing them with the addition operator. If you are new to jq or JSON I would highly suggest reading the jq manual and introducing JSON. These are excellent resources!

Leave a Reply

Your email address will not be published. Required fields are marked *