jq#

jq is a streaming JSON processor. The operator reaches for it the way they reach for awk on tab-separated text: a small language that filters, selects, reshapes, and projects, with predictable output the next pipeline stage can consume. jq expects valid JSON in and (by default) produces valid JSON out.

Sample input#

The recipes below operate on this document. Save it as buster.json to follow along.

{
  "name": "Buster",
  "breed": "Golden Retriever",
  "age": 4,
  "owner": { "name": "Sally" },
  "likes": ["bones", "balls", "dog biscuits"]
}

Selecting#

$ jq .                buster.json          # pretty-print, no transform
$ jq .name            buster.json          # one top-level key
$ jq '.name, .age'    buster.json          # multiple, comma-separated
$ jq .owner.name      buster.json          # nested path
$ jq '.likes[0]'      buster.json          # array index
$ jq '.likes[0:2]'    buster.json          # array slice
$ jq '.likes | length' buster.json         # length of an array

Filtering#

# On an array of objects, pull every name
$ jq '.[] | .name'             pets.json

# Drop matches the operator doesn't want
$ jq '.[] | select(.age > 5)'  pets.json

# Test for key presence
$ jq 'has("owner")'            buster.json

Reshaping#

# Build a flat array from selected fields
$ jq '[.name, .likes[]]'                       buster.json

# Project to a new object shape
$ jq '{pet: .name, owner: .owner.name}'        buster.json

# Delete keys the operator doesn't want downstream
$ jq 'del(.owner)'                             buster.json

Transforming#

# Map over an array, performing arithmetic
$ echo '[12, 14, 15]' | jq 'map(. - 2)'        # [10, 12, 13]

# Increment a scalar by 1
$ echo '{"eggs":2}'  | jq '.eggs + 1'          # 3

# Convert JSON-lines back to a single array
$ jq -s .  events.jsonl > events.json

# Convert a JSON array to JSON-lines for stream tools
$ jq -c '.[]' events.json > events.jsonl

References#