JQ 101

JQ is an amazing tool that allows you to manipulate JSON via the command line / bash.

To be frank I was a bit weirded out by people praising something so ’trivial’ back in the day, but then I realized how powerful this thing actually is. Manipulating JSON coming from web background may seem really simple task, but when you go to bash, it is … nightmare.

JQ makes things doable in surprisingly simple way.

The thing it is that it can be a bit hard to start with. Some people have asked me to provide them with several examples so they can have something to build on top of when developing their own stuff.

These are the basics, if you have mastered everything listed here, your logical next step would be to read the official docs like a real dev

So, this is my cheat sheet:

How to use

Invocation

You can cat a file and pipe it to JQ like:

cat file.json | jq 'something'

but it is generally preferred to do it like this:

jq 'something' < file.json

I personally prefer to add -r flag to JQ so it outputs raw

jq  -r 'something' < file.json

Sample data

We are going to be working with this JSON for most of the examples

{
    "data": [
        {
            "email": "user1@example.com",
            "username": "user1"
        },
        {
            "email": "user2@example.com",
            "username": "user2"
        }
    ],
    "users": [
        {
            "email": "user1@example.com",
            "user.name": "user1"
        },
        {
            "email": "user2@example.com",
            "user.name": "user2"
        }
    ]
}

Examples

Basic

Simple select everything

jq -r '.' < file.json

will give you the root of the document. Doesn’t matter if it is an object or array

Select property of an object

jq -r '.data' < file.json

returns an array containing all users in ‘.data’

Select first user in data

jq -r '.data[0]' < file.json

returns first object in ‘data’ array

Select all usernames is ‘.data’

jq -r '.data[].username' < file.json

returns

user1
user2

Select all usernames of ‘users’ array when keys contain dots

jq -r '.users[]["user.name"]' < file.json

returns

user1
user2

Selectors

Getting keys of an object

jq -r '.|keys' < file.json

gives you an array containing all keys ["data", "users"]

Getting keys of object on new lines

jq -r '.|keys[]' < file.json

returns

data
users

Select only users called ‘user1’ from ‘data’

jq -r '.data[] | select(.username="user1")'

gives you {"username": "user1", "email": "user1@example.com"}

Select the emails of all users called ‘user1’

jq -r '.data[] | select(.username="user1") | .email'

Create JSON

Create object with key username and value ‘user1’

jq -n --arg mykey username --arg myval user1 '{($mykey):$myval}'

Append property to object

jq -n --arg mykey username --arg myval user1 '{($mykey):$myval}' | jq -r '. |= . + {"email": "user1@example.com"}'

or simpler:

echo '{"username": "user1"}' | jq -r '. |= . + {"email": "user1@example.com"}'

both result in:

{
  "username": "user1",
  "email": "user1@example.com"
}

Change value of object property

jq -n '{ "username": "user1"}' | jq -r '.username="user11"'

Create array

jq -n '[]'

same as

echo '[]' | jq -r '.'

Set value of array element

jq -n '[1,2,3]' | jq -r '.[2] |=  5'

outputs [1,2,5]

Add element to array (of unknown length)

jq -n '[1,2,3]' | jq -r '.[.|length] |=  4'

result [1,2,3,4]