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)‘` |
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’` |
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)‘` |
| `jq ’[.[] \ | select(.active)]‘` |
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’` |
| `jq ‘.field \ | tonumber’` |
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}'
# 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) |
, | 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' |