Christoph's 2 Cents

A Backup for My Brain!

bashDevOpsjqLinuxOracle Linuxshell scripting

“Beer, Bash, and jq: Parsing JSON Like a Pro!”

Let me explain:

Beer: You should already know what this is 🍺.

Bash: You should probably know what this is, if not, you’ll need to read up on it .

jq: You may not know what this is. It is a powerful command-line tool for processing JSON data in terminal environments. It provides syntax for querying, filtering, transforming, and manipulating JSON data. With jq, you can easily extract specific data from a large JSON file, format and restructure JSON data, perform calculations and comparisons, and much more.

In this example I use jq to format the JSON contained in a file called beer.json to a pretty table format, including sorting by name, and including column headers.

{
    "results": [
    {
      "abv": "5.6",
      "name": "Luke's Lager",
      "brewery": "B33r Wars"
    },
    {
      "abv": "8.1",
      "name": "Dark Darth",
      "brewery": "B33r Wars"
    },
    {
      "abv": "3.2",
      "name": "Light Lenny",
      "brewery": "Cheap Beers"
    },
    {
      "abv": "3.2",
      "name": "Light Larry",
      "brewery": "Cheap Beers"
    },
    {
      "abv": "9.5",
      "name": "Go To Sleep",
      "brewery": "Brewtal Brews"
    },
    {
      "abv": "10.6",
      "name": "Ambulance Chaser",
      "brewery": "Brewtal Brews"
    }
  ],
  "status": "SUCCESS",
  "status code": 200
}

The data I want to display is in the results array.

The following command does all the magic:

jq -r '.results | sort_by(.name) | (["NAME","BREWERY","ABV"] | (.,map(length*"-"))), (.[] | [.name,.brewery,.abv]) | @csv' beer.json | column -t -s , | tr -d '"'

Let’s break down this command and understand how it works.

  • jq: The jq command is used to parse and manipulate JSON data.
  • -r: The -r option is used to output the results in raw format.
  • .results: This is the selector that chooses the results key in the JSON object.
  • sort_by(.name): This sorts the beer objects in the array by their name key.
  • (["NAME","BREWERY","ABV"] | (.,map(length*"-"))): This generates a header row and underline row with the column names.
  • (.[] | [.name,.brewery,.abv]): This generates an array of beer objects with their name, brewery, and abv keys.
  • @csv: This outputs the array as a comma-separated value (CSV) string.
  • column -t -s ,: This uses the column command to format the output as a table with columns separated by commas.
  • tr -d '"': This removes the double quotes from the output.

The outlook looks like this:

NAME              BREWERY        ABV
----              -------        ---
Ambulance Chaser  Brewtal Brews  10.6
Dark Darth        B33r Wars      8.1
Go To Sleep       Brewtal Brews  9.5
Light Larry       Cheap Beers    3.2
Light Lenny       Cheap Beers    3.2
Luke's Lager      B33r Wars      5.6

We get a nice, neat table that lists the beer names, breweries, and ABV percentages. It’s like having your own personal beer database.

Happy coding!

For more on jq, see: