Skip to main content
RunBook Academy

LinuxII · Shell and Command-Line OperationsStructured text

jq and structured text — JSON, YAML, and CSV at the command line

Intermediate⏱ ~8 minbashjqpython3

What you'll learn

  • Use jq to extract, filter, and reshape JSON
  • Recognise when YAML and CSV warrant a different tool
  • Build jq pipelines that handle missing keys and arrays
  • Avoid the common jq mistakes that produce empty results

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

Modern infrastructure tooling speaks JSON: cloud APIs, container runtimes, monitoring agents, configuration management, and most service-discovery systems. jq is the universal JSON processor on Linux and is the right tool for almost every JSON triage task.

The basic jq filter

A jq filter describes what to extract from a JSON value:

echo '{"name":"web01","status":"running"}' | jq '.name'
# "web01"

The leading . is the identity filter; .name selects the name field. By default jq pretty-prints its output.

Read-only / Safejq field access
$ echo "{\"name\":\"web01\",\"status\":\"running\"}" | jq ".name"
"web01"

Illustrative output

Read-only / Safejq raw output
$ echo '{"name":"web01","status":"running"}' | jq -r '.name'
web01

Illustrative output

Arrays and iteration

A JSON array is iterated with [] or , (the comma form generates multiple output records):

Read-only / Safeiterate array
$ echo '[{"name":"web01"},{"name":"db01"},{"name":"cache01"}]' | jq -r '.[].name'
web01
db01
cache01

Illustrative output

Read-only / Safejq filter and project
$ echo '[{"name":"web01","status":"running"},{"name":"db01","status":"stopped"}]' | jq -r '.[] | select(.status == "running") | .name'
web01

Illustrative output

Nested objects

For nested objects, use . chaining or [] for bracketed paths:

Read-only / Safenested access
$ echo '{"host":{"network":{"ip":"10.0.0.5"}}}' | jq -r '.host.network.ip'
10.0.0.5

Illustrative output

Read-only / Safenested arrays
$ echo '{"items":[{"name":"a"},{"name":"b"}]}' | jq -r '.items[] | .name'
a
b

Illustrative output

Constructing output

jq can build new JSON objects from the input:

Read-only / Safejq string interpolation
$ echo '[{"name":"web01","port":8080},{"name":"db01","port":5432}]' | jq -r '.[] | "(.name):(.port)"'
web01:8080
db01:5432

Illustrative output

Read-only / Safejq reshape
$ echo '[{"name":"web01","port":8080}]' | jq '[.[] | {host: .name, port: .port}]'
[
{
"host": "web01",
"port": 8080
}
]

Illustrative output

Handling missing keys gracefully

A common jq mistake is getting the literal text null for keys that do not exist in every record. The fix is the alternative operator. In jq that means two slash characters in a row

This file had MDX parser issues that the build process is recovering from.

Read-only / Safejq default value
$ echo '[{"name":"web01"},{"name":"db01","port":5432}]' | jq -r '.[] | "(.name):(.port // "unknown")"'
web01:unknown
db01:5432

Illustrative output

YAML and CSV

YAML and CSV are common in infrastructure but lack jq’s universal filters:

Read-only / Safeyq
$ yq -r '.spec.containers[].image' deployment.yaml
nginx:1.27
prom/node-exporter:1.8

Illustrative output

Read-only / Safepython for CSV
$ python3 -c 'import csv,sys; r=csv.DictReader(sys.stdin); print("\n".join(row["name"] for row in r))' < users.csv
alice
bob
carol

Illustrative output

Knowledge check

Knowledge check · 3 questions

  1. Q1. What is the effect of jq's -r flag?

  2. Q2. jq is installed by default on every modern Linux distribution.

  3. Q3. Which of the following are correct jq idioms? Select all that apply.

Passing score: 75%. Answers are checked in this browser.