Post

Learn jq: A Practical Guide

Learn jq: A Practical Guide

Learn jq by Example

If you work with JSON, jq is the fastest way to filter, transform, and query it from the command line. This guide is hands-on: it starts with a sample JSON file so you can copy it and run every command.


Sample JSON (save as sample.json)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
  "company": "Acme Labs",
  "founded": 2012,
  "active": true,
  "tags": ["analytics", "cloud", "ai"],
  "employees": [
    {
      "id": 1,
      "name": "Ava Patel",
      "role": "Engineer",
      "skills": ["go", "kubernetes", "jq"],
      "salary": 125000,
      "manager_id": 3
    },
    {
      "id": 2,
      "name": "Liam Chen",
      "role": "Designer",
      "skills": ["figma", "ux"],
      "salary": 98000,
      "manager_id": 3
    },
    {
      "id": 3,
      "name": "Noah Singh",
      "role": "Manager",
      "skills": ["leadership", "planning"],
      "salary": 145000,
      "manager_id": null
    }
  ],
  "projects": [
    {"code": "NX-1", "name": "Neon", "budget": 250000, "status": "active"},
    {"code": "QL-9", "name": "Quill", "budget": 120000, "status": "paused"},
    {"code": "SP-2", "name": "Sparrow", "budget": 80000, "status": "active"}
  ],
  "offices": {
    "nyc": {"headcount": 35, "opened": 2016},
    "blr": {"headcount": 22, "opened": 2019}
  }
}

1) Pretty-print JSON

1
jq '.' sample.json

jq formats JSON nicely by default.


2) Access fields

1
2
3
jq '.company' sample.json
jq '.founded' sample.json
jq '.offices.nyc.headcount' sample.json

3) Array indexing

1
2
jq '.employees[0].name' sample.json
jq '.projects[2].code' sample.json

4) List all items in an array

1
2
jq '.employees[].name' sample.json
jq '.projects[].name' sample.json

5) Filter with select

1
2
jq '.projects[] | select(.status == "active")' sample.json
jq '.employees[] | select(.salary > 100000)' sample.json

6) Transform output

1
2
jq '.employees[] | {name, role}' sample.json
jq '.projects[] | {code, budget}' sample.json

7) Create new fields

1
jq '.employees[] | . + {level: (if .role == "Manager" then "senior" else "staff" end)}' sample.json

8) Work with arrays

1
2
3
jq '.tags | length' sample.json
jq '.tags | sort' sample.json
jq '.tags | join(", ")' sample.json

9) Aggregate values

1
2
jq '[.employees[].salary] | add' sample.json
jq '.projects | map(.budget) | add' sample.json

10) Group and count

1
jq '.employees | group_by(.role) | map({role: .[0].role, count: length})' sample.json

11) Work with objects

1
2
jq '.offices | keys' sample.json
jq '.offices | to_entries' sample.json

12) Output plain text

Use -r for raw strings.

1
2
jq -r '.employees[].name' sample.json
jq -r '.projects[] | "\(.code): \(.status)"' sample.json

13) Multiple fields per line

1
jq -r '.employees[] | "\(.name)\t\(.role)\t\(.salary)"' sample.json

14) Conditional filters

1
jq '.employees[] | select(.skills | index("jq"))' sample.json

15) Sort arrays

1
2
jq '.employees | sort_by(.salary)' sample.json
jq '.projects | sort_by(.budget) | reverse' sample.json

Quick Reference

1
2
3
4
5
6
7
jq '.' sample.json                    # pretty print
jq '.field' sample.json               # access field
jq '.arr[]' sample.json               # iterate array
jq 'select(.x > 1)' sample.json       # filter
jq '{a, b}' sample.json               # create object
jq '.arr | length' sample.json        # array length
jq -r '.field' sample.json            # raw output

If you want, share your real JSON structure and I can craft exact jq filters for it.

This post is licensed under CC BY 4.0 by the author.