Skip to content

Instantly share code, notes, and snippets.

@copyleftdev
Created January 1, 2026 07:03
Show Gist options
  • Select an option

  • Save copyleftdev/5a8e828266e52ab1a8c6361f7777d54a to your computer and use it in GitHub Desktop.

Select an option

Save copyleftdev/5a8e828266e52ab1a8c6361f7777d54a to your computer and use it in GitHub Desktop.
The Ultimate JQ Cheat Sheet - Comprehensive guide to jq command-line JSON processor

πŸ”§ The Ultimate JQ Cheat Sheet

jq β€” lightweight, flexible command-line JSON processor

πŸ“‹ Table of Contents


Basics

# Pretty print JSON
cat file.json | jq '.'

# Compact output (single line)
jq -c '.' file.json

# Raw output (no quotes on strings)
jq -r '.name' file.json

# Read from string
echo '{"a":1}' | jq '.a'

# Null input (create JSON from scratch)
jq -n '{name: "test", value: 42}'

Navigation

# Get a field
jq '.name'                          # β†’ "John"

# Nested field
jq '.address.city'                  # β†’ "New York"

# Optional field (no error if missing)
jq '.missing?'                      # β†’ null

# Multiple fields
jq '.name, .age'                    # β†’ "John" \n 30

# Pipe through filters
jq '.address | .city'               # β†’ "New York"

Arrays

# First element
jq '.[0]'                           # β†’ first item

# Last element
jq '.[-1]'                          # β†’ last item

# Slice
jq '.[2:5]'                         # β†’ elements 2,3,4

# All elements (iterate)
jq '.[]'                            # β†’ each element

# Collect into array
jq '[.[] | .name]'                  # β†’ ["a","b","c"]

# Length
jq 'length'                         # β†’ 5

# First / Last
jq 'first'                          # β†’ first element
jq 'last'                           # β†’ last element

# Reverse
jq 'reverse'                        # β†’ [3,2,1]

# Flatten
jq 'flatten'                        # β†’ [1,2,3,4]

# Unique values
jq 'unique'                         # β†’ deduplicated

# Sort
jq 'sort'                           # β†’ sorted array
jq 'sort_by(.name)'                 # β†’ sorted by field

# Range
jq -n '[range(5)]'                  # β†’ [0,1,2,3,4]

Objects

# Get all keys
jq 'keys'                           # β†’ ["a","b","c"]

# Get all values
jq 'values'                         # β†’ [1,2,3]

# Check if key exists
jq 'has("name")'                    # β†’ true/false

# Add/update field
jq '. + {newfield: "value"}'        # β†’ merged object
jq '.name = "Jane"'                 # β†’ update in place

# Delete field
jq 'del(.unwanted)'                 # β†’ without field

# Rename key
jq '.newname = .oldname | del(.oldname)'

# Convert to entries
jq 'to_entries'                     # β†’ [{key,value},...]

# Convert from entries
jq 'from_entries'                   # β†’ {key: value, ...}

# Transform entries
jq 'with_entries(.value += 10)'     # β†’ modify all values

Filtering & Selection

# Select by condition
jq '.[] | select(.age > 21)'

# Select by field value
jq '.[] | select(.role == "admin")'

# Select non-null
jq '.[] | select(.email != null)'

# Select by type
jq '.. | numbers'                   # β†’ all numbers
jq '.. | strings'                   # β†’ all strings
jq '.. | booleans'                  # β†’ all booleans
jq '.. | arrays'                    # β†’ all arrays
jq '.. | objects'                   # β†’ all objects

# Map with filter
jq 'map(select(.active == true))'

# Contains
jq 'select(.tags | contains(["admin"]))'

# Inside (inverse of contains)
jq 'select(.role | inside("admin user"))'

# Test with regex
jq 'select(.email | test("@gmail"))'

# Limit results
jq '.[:5]'                          # β†’ first 5
jq 'limit(5; .[])'                  # β†’ first 5 iterated

Transformation

# Map over array
jq 'map(.name)'                     # β†’ extract field
jq 'map(. * 2)'                     # β†’ transform each

# Create new object
jq '{username: .name, mail: .email}'

# Construct array
jq '[.users[].name]'

# Group by field
jq 'group_by(.category)'            # β†’ [[...],[...]]

# Index by field
jq 'INDEX(.id)'                     # β†’ {id: obj, ...}

# Transpose
jq 'transpose'                      # β†’ pivot array

# Add to array
jq '. += ["new"]'                   # β†’ append

# Combine arrays
jq '. + ["extra"]'                  # β†’ concatenate

String Operations

# Uppercase / Lowercase
jq '.name | ascii_upcase'           # β†’ "JOHN"
jq '.name | ascii_downcase'         # β†’ "john"

# String length
jq '.name | length'                 # β†’ 4

# Split string
jq '.csv | split(",")'              # β†’ ["a","b","c"]

# Join array to string
jq '.tags | join(", ")'             # β†’ "a, b, c"

# String interpolation
jq '"Hello \(.name)!"'              # β†’ "Hello John!"

# Replace (regex)
jq '.text | gsub("old"; "new")'

# Trim whitespace
jq '.text | ltrimstr(" ") | rtrimstr(" ")'

# Starts/ends with
jq 'select(.url | startswith("https"))'
jq 'select(.file | endswith(".json"))'

# Match regex
jq '.text | match("[0-9]+")'        # β†’ match object
jq '.text | capture("(?<num>[0-9]+)")' # β†’ named groups

Math & Aggregation

# Sum array
jq 'add'                            # β†’ sum of array
jq '[.[].price] | add'              # β†’ sum field

# Average
jq 'add / length'                   # β†’ average

# Min / Max
jq 'min'                            # β†’ smallest
jq 'max'                            # β†’ largest
jq 'min_by(.price)'                 # β†’ object with min
jq 'max_by(.score)'                 # β†’ object with max

# Count
jq 'length'                         # β†’ count items
jq '[.[] | select(.active)] | length'  # β†’ count filtered

# Floor / Ceil / Round
jq '.price | floor'
jq '.price | ceil'  
jq '.price | round'

# Absolute value
jq '.delta | fabs'

# Math operations
jq '.a + .b'                        # add
jq '.a - .b'                        # subtract
jq '.a * .b'                        # multiply
jq '.a / .b'                        # divide
jq '.a % .b'                        # modulo

Conditionals

# If-then-else
jq 'if .age > 18 then "adult" else "minor" end'

# Alternative operator (default value)
jq '.missing // "default"'          # β†’ "default" if null

# Error suppression
jq '.field?'                        # β†’ null if missing

# Not
jq 'select(.active | not)'          # β†’ where not active

# And / Or
jq 'select(.a and .b)'
jq 'select(.a or .b)'

# Empty (skip output)
jq 'if .hide then empty else . end'

# Try-catch
jq 'try .bad.path catch "error"'

Advanced

# Recursive descent
jq '.. | .id? // empty'             # β†’ all id fields

# Walk and transform
jq 'walk(if type == "string" then ascii_upcase else . end)'

# Reduce
jq 'reduce .[] as $x (0; . + $x)'   # β†’ sum

# Define variables
jq '.price as $p | .qty * $p'

# Define functions
jq 'def double: . * 2; [.[] | double]'

# Path expressions
jq 'path(.a.b)'                     # β†’ ["a","b"]
jq 'getpath(["a","b"])'             # β†’ value at path
jq 'setpath(["a","b"]; 42)'         # β†’ set value

# Env variables
jq -n 'env.HOME'                    # β†’ /home/user

# Input/Inputs (multiple JSON docs)
jq -s '.'                           # β†’ slurp into array
jq -n '[inputs]'                    # β†’ stream to array

# Format as CSV
jq -r '.[] | [.name, .age] | @csv'

# Format as TSV
jq -r '.[] | [.name, .age] | @tsv'

# Base64
jq '.data | @base64'                # β†’ encode
jq '.encoded | @base64d'            # β†’ decode

# URI encode
jq '.query | @uri'

# JSON stringify
jq '. | @json'                      # β†’ escaped JSON string

# Dates
jq '.timestamp | todate'            # β†’ ISO date string
jq '"2024-01-01T00:00:00Z" | fromdateiso8601'  # β†’ epoch
jq 'now | todate'                   # β†’ current time

Real-World Examples

API Response Processing

# Extract data from paginated API
curl -s 'https://api.example.com/users' | \
  jq '.data[] | {id, name, email}'

# Get specific fields as CSV
curl -s 'https://api.example.com/users' | \
  jq -r '.data[] | [.id, .name, .email] | @csv'

Log Analysis

# Parse JSON logs, filter errors
cat app.log | jq -c 'select(.level == "error")'

# Count errors by type
cat app.log | jq -s 'group_by(.error_type) | 
  map({type: .[0].error_type, count: length})'

# Get last 10 errors
cat app.log | jq -s '[ .[] | select(.level == "error") ] | .[-10:]'

Config Manipulation

# Update config value
jq '.database.host = "newhost"' config.json > config.new.json

# Merge configs
jq -s '.[0] * .[1]' defaults.json overrides.json

# Remove sensitive fields before commit
jq 'del(.password, .api_key, .secret)' config.json

Data Transformation

# Convert array to lookup object
jq 'INDEX(.id)'

# Pivot data
jq 'group_by(.category) | 
  map({category: .[0].category, items: map(.name)})'

# Flatten nested structure
jq '[.. | objects | select(has("value")) | .value]'

Kubernetes / Docker

# Get pod names
kubectl get pods -o json | jq -r '.items[].metadata.name'

# Get container images
kubectl get pods -o json | jq -r '.items[].spec.containers[].image' | sort -u

# Docker inspect - get IP
docker inspect container_id | jq -r '.[0].NetworkSettings.IPAddress'

AWS CLI

# List EC2 instance IDs and states
aws ec2 describe-instances | \
  jq -r '.Reservations[].Instances[] | [.InstanceId, .State.Name] | @tsv'

# Get S3 bucket sizes
aws s3api list-buckets | jq -r '.Buckets[].Name'

CLI Flags Reference

Flag Description
-r Raw output (no JSON quotes)
-c Compact output
-s Slurp (read all inputs into array)
-n Null input (don't read stdin)
-e Exit with error if result is null/false
-S Sort keys
-C Colorize output
-M Monochrome output
-f Read filter from file
--arg name val Pass string variable
--argjson name val Pass JSON variable
--slurpfile var file Load file into variable

Quick Reference Card

Task Command
Pretty print jq '.'
Get field jq '.field'
Get nested jq '.a.b.c'
Array element jq '.[0]'
All elements jq '.[]'
Filter jq '.[] | select(.x > 5)'
Map jq 'map(.field)'
Keys jq 'keys'
Length jq 'length'
Sort jq 'sort_by(.field)'
Unique jq 'unique'
Group jq 'group_by(.field)'
Sum jq 'add'
Default jq '.x // "default"'
Delete jq 'del(.field)'
Merge jq '. + {new: 1}'
To CSV jq -r '@csv'

Version: jq 1.6+ | License: MIT | More: https://jqlang.github.io/jq/manual/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment