Skip to main content

jq Filters and Transformations

Learning Focus

jq's real power is transforming JSON — selecting subsets, reshaping objects, constructing entirely new structures from existing data.

The Pipe Operator |

Chain filters together:

echo '{"user":{"profile":{"name":"Alice"}}}' | jq '.user | .profile | .name'
# "Alice"

Construct New Objects

curl -s https://api.github.com/users/torvalds | \
jq '{login: .login, repos: .public_repos, joined: .created_at}'

Construct New Arrays

curl -s "https://api.github.com/repos/stedolan/jq/commits?per_page=5" | \
jq '[.[] | {sha: .sha[:7], msg: .commit.message, author: .commit.author.name}]'

select — Filter Elements

echo '[{"id":1,"active":true},{"id":2,"active":false}]' | \
jq '[.[] | select(.active == true)]'
# [{"id":1,"active":true}]

map — Transform Every Element

echo '[1,2,3,4,5]' | jq 'map(. * 2)'
# [2,4,6,8,10]

echo '[{"price":10},{"price":25}]' | jq 'map(.price * 1.1)'
# [11.0,27.5]

reduce — Accumulate

echo '[1,2,3,4,5]' | jq 'reduce .[] as $x (0; . + $x)'
# 15

String Interpolation

echo '{"name":"Alice","age":30}' | jq -r '"User: \(.name), Age: \(.age)"'
# User: Alice, Age: 30

Conditionals

echo '[1,2,3,4,5]' | jq '[.[] | if . > 3 then "big" else "small" end]'
# ["small","small","small","big","big"]

Alternative Operator // (Default Value)

echo '{"name": null}' | jq '.name // "unknown"'
# "unknown"
echo '{}' | jq '.missing // "default"'
# "default"

Object Utilities

echo '{"a":1,"b":2}' | jq 'keys' # ["a","b"]
echo '{"a":1,"b":2}' | jq 'values' # [1,2]
echo '{"a":1,"b":2}' | jq 'to_entries' # [{"key":"a","value":1},...]
echo '[{"key":"a","value":1}]' | jq 'from_entries' # {"a":1}

Concept Map

Concept Flow

Input JSON
└── Pipe ( | )
├── select(cond) → Filter matching elements
├── map(expr) → Transform each element
├── { key: .field } → Construct new object
└── reduce .[] as $x → Accumulate value
└── Transformed JSON Output

Common Pitfalls

PitfallConsequencePrevention
map(f) vs `.[]f`map returns array; .[] streams
select without [] wrapperStreams records, not an array`[.[]
String interpolation without -rOutputs "string" with quotesAdd -r flag
Chaining on nullCascading null errorsUse // alternative operator

What's Next