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]