| name | jq |
| description | Expert jq usage for JSON querying, filtering, transformation, and pipeline integration. Practical patterns for real shell workflows. |
| category | AI & Agents |
| source | antigravity |
| tags | ["node","api","claude","ai","automation","workflow","design","image","security","docker"] |
| url | https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/jq |
jq — JSON Querying and Transformation
Overview
jq is the standard CLI tool for querying and reshaping JSON. This skill covers practical, expert-level usage: filtering deeply nested data, transforming structures, aggregating values, and composing jq into shell pipelines. Every example is copy-paste ready for real workflows.
When to Use This Skill
- Use when parsing JSON output from APIs, CLI tools (AWS, GitHub, kubectl, docker), or log files
- Use when transforming JSON structure (rename keys, flatten arrays, group records)
- Use when the user needs
jq inside a bash script or one-liner
- Use when explaining what a complex
jq expression does
How It Works
jq takes a filter expression and applies it to JSON input. Filters compose with pipes (|), and jq handles arrays, objects, strings, numbers, booleans, and null natively.
Basic Selection
echo '{"name":"alice","age":30}' | jq '.name'
echo '{"user":{"email":"a@b.com"}}' | jq '.user.email'
echo '[10, 20, 30]' | jq '.[1]'
echo '[1,2,3,4,5]' | jq '.[2:4]'
echo '[{"id":1},{"id":2}]' | jq '.[]'
Filtering with select
echo '[{"role":"admin"},{"role":"user"},{"role":"admin"}]' \
| jq '[.[] | select(.role == "admin")]'
curl -s https://api.github.com/repos/owner/repo/issues \
| jq '[.[] | select(.comments > 5)]'
jq '[.[] | select(.email != null)]'
jq '[.[] | select(.active == true and .score >= 80)]'
Mapping and Transformation
echo '[{"name":"alice","age":30},{"name":"bob","age":25}]' \
| jq '[.[] | .name]'
jq 'map(.name)'
jq '[.[] | {user: .name, years: .age}]'
jq '[.[] | . + {senior: (.age > 28)}]'
jq '[.[] | {username: .name, email_address: .email}]'
Aggregation and Reduce
echo '[1, 2, 3, 4, 5]' | jq 'add'
jq '[.[].price] | add'
jq 'length'
jq 'max_by(.score)'
jq 'min_by(.created_at)'
echo '[1,2,3,4,5]' | jq 'reduce .[] as $x (0; . + $x)'
jq 'group_by(.department)'
jq 'group_by(.status) | map({status: .[0].status, count: length})'
String Interpolation and Formatting
jq -r '.[] | "\(.name) is \(.age) years old"'
jq -r '.[] | [.name, .age, .email] | @csv'
jq -r '.[] | [.name, .score] | @tsv'
jq -r '.query | @uri'
jq -r '.data | @base64'
Working with Keys and Paths
jq 'keys'
jq 'has("email")'
jq 'del(.password)'
jq '[.[] | del(.internal_id, .raw_payload)]'
jq '.. | .id? // empty'
jq '[paths(scalars)]'
Conditionals and Error Handling
jq 'if .score >= 90 then "A" elif .score >= 80 then "B" else "C" end'
jq '.nickname // .name'
jq '[.[] | try .nested.value catch null]'
jq '.[] | .optional_field // empty'
Practical Shell Integration
jq '.users' data.json
jq -c '.[]' records.json | while IFS= read -r record; do
echo "Processing: $record"
done
STATUS="active"
jq --arg s "$STATUS" '[.[] | select(.status == $s)]'
jq --argjson threshold 42 '[.[] | select(.value > $threshold)]'
jq -s '.' records.ndjson
jq -s 'add' file1.json file2.json
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'
gh pr list --json number,title | jq -r '.[] | "\(.number)\t\(.title)"'
aws ec2 describe-instances \
| jq -r '.Reservations[].Instances[] | select(.State.Name=="running") | .InstanceId'
docker inspect $(docker ps -q) | jq -r '.[] | "\(.Name)\t\(.Config.Image)"'
Advanced Patterns
jq '[.names, .scores] | transpose | map({name: .[0], score: .[1]})'
jq 'flatten(1)'
jq 'unique_by(.email)'