6.5 KiB
6.5 KiB
jq: JSON Query and Extraction Reference
Goal: Extract specific data from JSON without reading entire file.
The Essential Pattern
jq '.field' file.json
Use -r flag for raw output (removes quotes from strings):
jq -r '.field' file.json
Use -r by default for string values - cleaner output.
Core Patterns (80% of Use Cases)
1. Extract Top-Level Field
jq -r '.version' package.json
jq -r '.name' package.json
2. Extract Nested Field
jq -r '.dependencies.react' package.json
jq -r '.scripts.build' package.json
jq -r '.config.database.host' config.json
3. Extract Multiple Fields
jq '{name, version, description}' package.json
Creates object with just those fields.
Or as separate lines:
jq -r '.name, .version' package.json
4. Extract from Array by Index
jq '.[0]' array.json # First element
jq '.items[2]' data.json # Third element
5. Extract All Array Elements
jq '.[]' array.json # All elements
jq '.items[]' data.json # All items
6. Extract Field from Each Array Element
jq -r '.dependencies | keys[]' package.json # All dependency names
jq -r '.items[].name' data.json # Name from each item
7. Filter Array by Condition
jq '.items[] | select(.active == true)' data.json
jq '.items[] | select(.price > 100)' data.json
8. Get Object Keys
jq -r 'keys[]' object.json
jq -r '.dependencies | keys[]' package.json
9. Check if Field Exists
jq 'has("field")' file.json
10. Handle Missing Fields (Use // for Default)
jq -r '.field // "default"' file.json
Common Real-World Workflows
"What version is this package?"
jq -r '.version' package.json
"What's the main entry point?"
jq -r '.main' package.json
"List all dependencies"
jq -r '.dependencies | keys[]' package.json
"What version of React?"
jq -r '.dependencies.react' package.json
"List all scripts"
jq -r '.scripts | keys[]' package.json
"Get specific script command"
jq -r '.scripts.build' package.json
"Check TypeScript compiler options"
jq '.compilerOptions' tsconfig.json
"Get target from tsconfig"
jq -r '.compilerOptions.target' tsconfig.json
"List all services from docker-compose JSON"
jq -r '.services | keys[]' docker-compose.json
"Get environment variables for a service"
jq '.services.api.environment' docker-compose.json
Advanced Patterns (20% Use Cases)
Combine Multiple Queries
jq '{version, deps: (.dependencies | keys)}' package.json
Map Array Elements
jq '[.items[] | .name]' data.json # Array of names
Count Array Length
jq '.items | length' data.json
jq '.dependencies | length' package.json
Sort Array
jq '.items | sort_by(.name)' data.json
Group and Transform
jq 'group_by(.category)' data.json
Complex Filter
jq '.items[] | select(.active and .price > 100) | .name' data.json
Pipe Composition
jq uses | for piping within queries:
jq '.items | map(.name) | sort' data.json
Can also pipe to shell commands:
jq -r '.dependencies | keys[]' package.json | wc -l # Count dependencies
jq -r '.dependencies | keys[]' package.json | sort # Sorted dependency list
Common Flags
-r- Raw output (no quotes) - USE THIS FOR STRINGS-c- Compact output (single line)-e- Exit with error if output is false/null-S- Sort object keys-M- Monochrome (no colors)
Default to -r for string extraction.
Handling Edge Cases
If Field Might Not Exist
jq -r '.field // "not found"' file.json
If Result Might Be Null
jq -r '.field // empty' file.json # Output nothing if null
If Array Might Be Empty
jq -r '.items[]? // empty' file.json # ? suppresses errors
Multiple Possible Paths
jq -r '.field1 // .field2 // "default"' file.json
Error Handling
If field doesn't exist:
# BAD: jq '.nonexistent' file.json
# → null (but no error)
# GOOD: Check existence first
jq -e 'has("field")' file.json && jq '.field' file.json
Or use default:
jq -r '.field // "not found"' file.json
Integration with Other Tools
With ast-grep
# Get dependencies, then search code for usage
jq -r '.dependencies | keys[]' package.json | while read dep; do
rg -l "from ['\"]$dep['\"]"
done
With Edit Tool
Common workflow:
- Use jq to extract current value
- Modify value
- Use Edit tool to update JSON (or jq for complex updates)
Reading STDIN
echo '{"key":"value"}' | jq -r '.key'
Best Practices
1. Always Use -r for String Fields
# BAD: jq '.version' package.json → "1.0.0" (with quotes)
# GOOD: jq -r '.version' package.json → 1.0.0 (raw)
2. Test Queries on Small Examples First
echo '{"test":"value"}' | jq -r '.test'
3. Use // for Defaults
jq -r '.field // "default"' file.json
4. Use keys[] for Object Properties
jq -r 'keys[]' object.json
5. Combine with Shell Pipes
jq -r '.dependencies | keys[]' package.json | grep react
Quick Reference
Most Common Commands
# Single field
jq -r '.field' file.json
# Nested field
jq -r '.parent.child' file.json
# Array element
jq '.array[0]' file.json
# All array elements
jq '.array[]' file.json
# Object keys
jq -r 'keys[]' file.json
# Filter array
jq '.array[] | select(.field == "value")' file.json
# Multiple fields
jq '{field1, field2}' file.json
# With default
jq -r '.field // "default"' file.json
When to Use Read Instead
Use Read tool when:
- File is < 50 lines
- Need to see overall structure
- Making edits (need full context)
- Exploring unknown JSON structure
Use jq when:
- File is large
- Know exactly what field(s) are needed
- Want to save context tokens
Summary
Default pattern:
jq -r '.field' file.json
Key principles:
- Use
-rfor string output (raw, no quotes) - Use
.notation for nested fields - Use
[]for array access - Use
//for defaults - Use
keys[]for object properties - Pipe with
|inside jq, pipe to shell after
Massive context savings: Extract only what is needed instead of reading entire JSON files.