Skip to content

jq Cheatsheet - Command-line JSON Processor

Installation

Platform Command
Ubuntu/Debian sudo apt-get update && sudo apt-get install jq
RHEL/CentOS/Fedora sudo yum install jq or sudo dnf install jq
Arch Linux sudo pacman -S jq
macOS (Homebrew) brew install jq
macOS (MacPorts) sudo port install jq
Windows (Chocolatey) choco install jq
Windows (Scoop) scoop install jq
Docker docker run --rm -i stedolan/jq
Verify Installation jq --version

Basic Commands

Command Description
jq '.' Pretty-print JSON (identity filter)
jq '.fieldname' Extract specific field value
jq '.field1, .field2' Extract multiple fields
jq '.parent.child' Extract nested field value
jq '.[0]' Get first element of array
jq '.[1:3]' Array slice (elements 1-2)
jq '.[]' Iterate through all array elements
jq '.[].fieldname' Extract field from each array element
jq 'length' Get length of array or object
jq 'keys' Get all keys from object (sorted)
jq 'keys_unsorted' Get all keys in original order
jq 'values' Get all values from object
jq 'has("key")' Check if object has specific key
jq 'type' Get type of value (string, number, array, etc.)
jq -r '.field' Raw output (no quotes for strings)
jq -c '.' Compact output (no pretty-printing)
jq -S '.' Sort object keys in output
jq '.' file.json Read and process JSON from file
jq -n '{key: "value"}' Create JSON without input
jq 'empty' Produce no output

Advanced Usage

Command Description
jq '.[] \| select(.age > 25)' Filter array elements by condition
jq 'map(. * 2)' Apply operation to each array element
jq '{name: .firstName, age: .userAge}' Construct new object with renamed fields
jq 'if .age >= 18 then "adult" else "minor" end' Conditional logic
jq 'group_by(.category)' Group array elements by field value
jq 'sort' Sort array in ascending order
jq 'sort_by(.fieldname)' Sort array of objects by field
jq 'reverse' Reverse array order
jq 'unique' Get unique values from array
jq 'unique_by(.field)' Get unique objects by field value
jq 'reduce .[] as $item (0; . + $item)' Reduce array to single value (sum example)
jq '.. \| numbers' Recursively find all numbers
jq '.field // "default"' Use default value if field is null/missing
jq 'try .field catch "error"' Error handling with fallback
jq 'flatten' Flatten nested arrays one level
jq 'flatten(2)' Flatten nested arrays N levels
jq '. + {newField: "value"}' Add or update fields
jq 'del(.fieldname)' Delete field from object
jq 'del(.[2])' Delete element from array by index
jq 'to_entries' Convert object to key-value pairs array
jq 'from_entries' Convert key-value pairs to object
jq 'with_entries(.value \|= . * 2)' Transform all object values
jq '[.[] \| select(.active)]' Filter and collect into new array
jq 'min' Get minimum value from array
jq 'max' Get maximum value from array
jq 'min_by(.field)' Get object with minimum field value
jq 'max_by(.field)' Get object with maximum field value
jq 'add' Sum array of numbers or concatenate strings
jq 'any(. > 5)' Check if any element matches condition
jq 'all(. > 0)' Check if all elements match condition

String Operations

Command Description
jq '"Hello \(.name)"' String interpolation
jq '.field \| tostring' Convert value to string
jq '.field \| tonumber' Convert string to number
jq 'split("/")' Split string into array
jq 'join("-")' Join array elements into string
jq 'startswith("prefix")' Check if string starts with prefix
jq 'endswith("suffix")' Check if string ends with suffix
jq 'contains("substring")' Check if string contains substring
jq 'ltrimstr("prefix")' Remove prefix from string
jq 'rtrimstr("suffix")' Remove suffix from string
jq 'ascii_downcase' Convert string to lowercase
jq 'ascii_upcase' Convert string to uppercase
jq 'test("regex")' Test if string matches regex
jq 'match("regex")' Get regex match details
jq 'capture("(?<name>\\w+)")' Capture named regex groups
jq 'sub("old"; "new")' Replace first occurrence
jq 'gsub("old"; "new")' Replace all occurrences

Configuration

Command-Line Options

# Raw output (no JSON quotes for strings)
jq -r '.field' file.json

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

# Sort object keys
jq -S '.' file.json

# Slurp mode (read entire input into array)
jq -s '.' file1.json file2.json

# Null input (don't read stdin)
jq -n '{created: now}'

# Exit status based on output
jq -e '.field' file.json  # Exit 1 if false/null

# Color output control
jq -C '.' file.json  # Force color
jq -M '.' file.json  # Disable color

# Custom indentation
jq --indent 4 '.' file.json
jq --tab '.' file.json

# Read filter from file
jq -f filter.jq data.json

# Pass variables to jq
jq --arg name "John" '{user: $name}' -n
jq --argjson count 42 '{total: $count}' -n
jq --slurpfile data file.json '{imported: $data}' -n

# Multiple inputs
jq --jsonargs '. | @json' --args arg1 arg2 arg3

Environment Variables

# Customize output colors (format: null:false:true:numbers:strings:arrays:objects)
export JQ_COLORS="0;90:0;91:0;92:0;93:0;94:0;95:0;96"

# Default colors (bright theme)
export JQ_COLORS="1;30:0;39:0;39:0;39:0;32:1;39:1;39"

# Disable colors entirely
export NO_COLOR=1

Filter Files

Create reusable filter files for complex operations:

# filter.jq
.data[]
| select(.status == "active")
| {
    id: .id,
    name: .name,
    created: .timestamp | strftime("%Y-%m-%d")
  }

# Usage
jq -f filter.jq data.json

Common Use Cases

Use Case: Parse API Response

# Extract specific fields from API response
curl -s https://api.example.com/users | jq '.users[] | {name: .name, email: .email}'

# Filter active users and get their IDs
curl -s https://api.example.com/users | jq -r '.users[] | select(.active == true) | .id'

# Count total results
curl -s https://api.example.com/users | jq '.users | length'

Use Case: Process AWS CLI Output

# List EC2 instance IDs and names
aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | "\(.InstanceId) \(.Tags[]|select(.Key=="Name")|.Value)"'

# Get S3 bucket sizes
aws s3api list-buckets | jq -r '.Buckets[].Name' | while read bucket; do
  aws s3 ls s3://$bucket --recursive --summarize | grep "Total Size" | jq -R ". | {bucket: \"$bucket\", size: .}"
done

# Filter running instances
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(.State.Name == "running")'

Use Case: Log Analysis

# Parse JSON logs and extract errors
cat application.log | jq -r 'select(.level == "ERROR") | "\(.timestamp) \(.message)"'

# Count log entries by level
cat application.log | jq -s 'group_by(.level) | map({level: .[0].level, count: length})'

# Find slow requests (response time > 1000ms)
cat access.log | jq 'select(.response_time > 1000) | {path: .path, time: .response_time}'

Use Case: Transform Data Structure

# Convert flat structure to nested
echo '[{"id":1,"name":"John","dept":"IT"},{"id":2,"name":"Jane","dept":"HR"}]' | \
jq 'group_by(.dept) | map({department: .[0].dept, employees: map({id: .id, name: .name})})'

# Merge multiple JSON files
jq -s 'add' file1.json file2.json file3.json

# Create CSV from JSON
jq -r '.[] | [.id, .name, .email] | @csv' data.json

Use Case: Configuration Management

# Extract specific config value
jq -r '.database.host' config.json

# Update config value
jq '.database.port = 5432' config.json > config.tmp && mv config.tmp config.json

# Merge config files
jq -s '.[0] * .[1]' base-config.json override-config.json > final-config.json

# Validate required fields exist
jq -e '.database.host and .database.port' config.json && echo "Valid" || echo "Invalid"

Best Practices

  • Use -r for scripts: When extracting values for shell scripts, use raw output to avoid quoted strings
  • Pipe efficiently: Chain operations with | instead of multiple jq calls for better performance
  • Test filters incrementally: Build complex filters step-by-step, testing each part with sample data
  • Handle missing fields: Use // operator or try-catch to provide defaults for optional fields
  • Use -e for validation: Set exit status based on output for reliable error handling in scripts
  • Store complex filters: Save reusable filters in .jq files and use -f option for maintainability
  • Quote properly: Single-quote jq filters in shell to prevent shell expansion of special characters
  • Use select before map: Filter data before transforming to improve performance on large datasets
  • Leverage --arg for safety: Pass external values as arguments instead of string interpolation to prevent injection
  • Profile large operations: Use --debug flag to understand filter execution and optimize bottlenecks

Troubleshooting

Issue Solution
parse error: Invalid numeric literal Check JSON syntax - likely missing quotes around strings or trailing commas
jq: error: syntax error Verify filter syntax - ensure proper pipe usage and bracket matching
Output shows null unexpectedly Field doesn't exist - use .field // "default" or has("field") to check first
Cannot index array with string Trying to access object field on array - use .[] to iterate or .[0] for specific index
Cannot iterate over null Input is null or empty - use -n flag or check input source
Colors not showing in output Pipe to less -R or use jq -C to force color output
jq: command not found Install jq using package manager or download from https://jqlang.github.io/jq/
Very slow performance on large files Use streaming parser with --stream or filter early in pipeline
Special characters breaking filter Wrap entire filter in single quotes and escape internal single quotes with '\''
Need to process multiple JSON objects (not array) Use jq -s '.' to slurp into array or process line-by-line with jq -c
Error: break or continue outside loop These keywords only work inside while/until loops - restructure logic
Memory issues with large datasets Use streaming mode --stream or process in chunks with limit(n; .)

Quick Reference: Operators

Operator Description Example
. Identity / current value jq '.'
.field Object field access jq '.name'
.[n] Array index access jq '.[0]'
.[] Array/object iteration jq '.[]'
\| Pipe (chain operations) jq '.field \| length'
, Multiple outputs jq '.a, .b'
// Alternative operator jq '.field // "default"'
? Optional operator (suppress errors) jq '.field?'
+ Addition / concatenation jq '.a + .b'
- Subtraction / array difference jq '.a - .b'
* Multiplication / object merge jq '. * {new: "field"}'
/ Division jq '.total / .count'
% Modulo jq '. % 2'
== Equality jq '.a == .b'
!= Inequality jq '.a != .b'
<, <=, >, >= Comparisons jq '.age > 18'
and, or, not Logical operators jq '.a and .b'