Basics of jq

What is jq?

jq is a command-line tool for processing JSON.

It lets you:

Think of it as sed/awk for JSON.


Installation

Debian / Ubuntu

sudo apt install jq

Check:

jq --version

Basic Usage

Given:

{
  "name": "Alice",
  "age": 25
}

Put it in user.json.

Pretty-print it:

jq . user.json

Or:

cat user.json | jq .

jq . means:

Take the input JSON and output it unchanged, formatted nicely.


Extracting Values

Use .field:

jq '.name' user.json

Output:

"Alice"
jq '.age' user.json

Output:

25

Multiple levels:

{
  "user": {
    "name": "Alice"
  }
}
jq '.user.name' data.json

Raw Strings

By default, jq outputs JSON strings with quotes:

jq '.name' user.json
"Alice"

Use -r for raw output:

jq -r '.name' user.json
Alice

This is especially useful in shell scripts.


Arrays

Given:

{
  "users": [
    {
      "name": "Alice",
      "age": 25
    },
    {
      "name": "Bob",
      "age": 30
    }
  ]
}

Get the array:

jq '.users' users.json

Get the first item:

jq '.users[0]' users.json

Get the first user’s name:

jq '.users[0].name' users.json

Get all names:

jq '.users[].name' users.json

Output:

"Alice"
"Bob"

Array Indexing

.[0]

First element.

.[1]

Second element.

.[-1]

Last element.

Slices:

.[0:3]

First three elements.


Iterating with []

Given:

["apple", "banana", "orange"]
jq '.[]' fruits.json

Produces each element separately:

"apple"
"banana"
"orange"

This is one of the most important jq operations.


Filtering

Given:

[
  { "name": "Alice", "age": 25 },
  { "name": "Bob", "age": 17 },
  { "name": "Carol", "age": 30 }
]

Find users over 18:

jq '.[] | select(.age >= 18)' users.json

Get only their names:

jq '.[] | select(.age >= 18) | .name' users.json

Output:

"Alice"
"Carol"

The Pipe |

The pipe passes the result of one operation into another.

.users[] | .name

Read this as:

Get .users, iterate over it, then get .name from each user.

Another example:

.users[] | select(.age >= 18) | .name

Read it as:

Get users → iterate → keep adults → get their names.


Creating Objects

You can construct new JSON objects:

jq '.[] | {name: .name, age: .age}' users.json

You can shorten repeated field names:

.[] | {name, age}

Renaming Fields

.[] | {
  username: .name,
  years_old: .age
}

Result:

{
  "username": "Alice",
  "years_old": 25
}

Arrays of Values

Get just the names as an array:

jq '[.[] | .name]' users.json

Result:

["Alice", "Bob", "Carol"]

The [...] collects the generated results into an array.


Length

length

For an array:

jq 'length' users.json

For a string:

.name | length

Sorting

Sort an array:

sort

Sort users by age:

sort_by(.age)

Descending:

sort_by(.age) | reverse

Selecting Fields

Given:

{
  "name": "Alice",
  "age": 25,
  "email": "alice@example.com"
}

Select multiple fields:

{name, email}

Result:

{
  "name": "Alice",
  "email": "alice@example.com"
}

Default Values

Use //:

.username // "anonymous"

If .username is null or missing, "anonymous" is returned.

Example:

jq '.username // "anonymous"' user.json

Conditionals

if .age >= 18 then "adult" else "minor" end

Example:

jq '.[] | {
  name,
  status: (if .age >= 18 then "adult" else "minor" end)
}' users.json

String Interpolation

Use \(...):

"Hello, \(.name)!"

Example:

jq '.[] | "User: \(.name), Age: \(.age)"' users.json

Working with Command Output

A common use is processing JSON returned by another command:

some-command | jq '.name'

For example:

curl -s https://example.com/api/users | jq '.[].name'

jq is therefore very useful when working with APIs.


Useful Options

Pretty print

jq .

Raw strings

jq -r '.name'

Compact JSON

jq -c .

Read from a file

jq '.users' users.json

Read from stdin

cat users.json | jq '.users'

Common Patterns

Get all names

.[].name

Filter and get a field

.[] | select(.active == true) | .name

Count items

length

Count filtered items

[.[] | select(.active == true)] | length

Extract nested data

.users[].profile.email

Create a smaller object

.[] | {id, name}

Convert objects into strings

.[] | "\(.id): \(.name)"

The jq Mental Model

The most important thing to understand is:

JSON input

jq filter

JSON output

For example:

.users[]

means:

input

.users

each element

And:

.users[] | select(.age >= 18) | .name

means:

users

each user

keep adults

get name

jq Cheat Sheet

Task Filter
Pretty print .
Field .name
Nested field .user.name
Array element .[0]
Iterate array .[]
Filter select(...)
Pipe |
Length length
Sort sort
Sort by field sort_by(.age)
Default value .name // "Unknown"
Create object {name, age}
Create array [.[]]
Raw output jq -r
Compact output jq -c

The Core 5 to Learn First

If you’re just starting, focus on these:

.field
[]
|
select(...)
{field1, field2}

Once these make sense, most everyday jq commands become much easier to read.