# jq: JSON Query and Extraction Reference **Goal: Extract specific data from JSON without reading entire file.** ## The Essential Pattern ```bash jq '.field' file.json ``` Use `-r` flag for raw output (removes quotes from strings): ```bash 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 ```bash jq -r '.version' package.json jq -r '.name' package.json ``` ## 2. Extract Nested Field ```bash jq -r '.dependencies.react' package.json jq -r '.scripts.build' package.json jq -r '.config.database.host' config.json ``` ## 3. Extract Multiple Fields ```bash jq '{name, version, description}' package.json ``` Creates object with just those fields. Or as separate lines: ```bash jq -r '.name, .version' package.json ``` ## 4. Extract from Array by Index ```bash jq '.[0]' array.json # First element jq '.items[2]' data.json # Third element ``` ## 5. Extract All Array Elements ```bash jq '.[]' array.json # All elements jq '.items[]' data.json # All items ``` ## 6. Extract Field from Each Array Element ```bash jq -r '.dependencies | keys[]' package.json # All dependency names jq -r '.items[].name' data.json # Name from each item ``` ## 7. Filter Array by Condition ```bash jq '.items[] | select(.active == true)' data.json jq '.items[] | select(.price > 100)' data.json ``` ## 8. Get Object Keys ```bash jq -r 'keys[]' object.json jq -r '.dependencies | keys[]' package.json ``` ## 9. Check if Field Exists ```bash jq 'has("field")' file.json ``` ## 10. Handle Missing Fields (Use // for Default) ```bash jq -r '.field // "default"' file.json ``` --- # Common Real-World Workflows ## "What version is this package?" ```bash jq -r '.version' package.json ``` ## "What's the main entry point?" ```bash jq -r '.main' package.json ``` ## "List all dependencies" ```bash jq -r '.dependencies | keys[]' package.json ``` ## "What version of React?" ```bash jq -r '.dependencies.react' package.json ``` ## "List all scripts" ```bash jq -r '.scripts | keys[]' package.json ``` ## "Get specific script command" ```bash jq -r '.scripts.build' package.json ``` ## "Check TypeScript compiler options" ```bash jq '.compilerOptions' tsconfig.json ``` ## "Get target from tsconfig" ```bash jq -r '.compilerOptions.target' tsconfig.json ``` ## "List all services from docker-compose JSON" ```bash jq -r '.services | keys[]' docker-compose.json ``` ## "Get environment variables for a service" ```bash jq '.services.api.environment' docker-compose.json ``` --- # Advanced Patterns (20% Use Cases) ## Combine Multiple Queries ```bash jq '{version, deps: (.dependencies | keys)}' package.json ``` ## Map Array Elements ```bash jq '[.items[] | .name]' data.json # Array of names ``` ## Count Array Length ```bash jq '.items | length' data.json jq '.dependencies | length' package.json ``` ## Sort Array ```bash jq '.items | sort_by(.name)' data.json ``` ## Group and Transform ```bash jq 'group_by(.category)' data.json ``` ## Complex Filter ```bash jq '.items[] | select(.active and .price > 100) | .name' data.json ``` --- # Pipe Composition jq uses `|` for piping within queries: ```bash jq '.items | map(.name) | sort' data.json ``` Can also pipe to shell commands: ```bash 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 ```bash jq -r '.field // "not found"' file.json ``` ## If Result Might Be Null ```bash jq -r '.field // empty' file.json # Output nothing if null ``` ## If Array Might Be Empty ```bash jq -r '.items[]? // empty' file.json # ? suppresses errors ``` ## Multiple Possible Paths ```bash jq -r '.field1 // .field2 // "default"' file.json ``` --- # Error Handling If field doesn't exist: ```bash # 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: ```bash jq -r '.field // "not found"' file.json ``` --- # Integration with Other Tools ## With ast-grep ```bash # 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: 1. Use jq to extract current value 2. Modify value 3. Use Edit tool to update JSON (or jq for complex updates) ## Reading STDIN ```bash echo '{"key":"value"}' | jq -r '.key' ``` --- # Best Practices ## 1. Always Use -r for String Fields ```bash # 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 ```bash echo '{"test":"value"}' | jq -r '.test' ``` ## 3. Use // for Defaults ```bash jq -r '.field // "default"' file.json ``` ## 4. Use keys[] for Object Properties ```bash jq -r 'keys[]' object.json ``` ## 5. Combine with Shell Pipes ```bash jq -r '.dependencies | keys[]' package.json | grep react ``` --- # Quick Reference ## Most Common Commands ```bash # 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:** ```bash jq -r '.field' file.json ``` **Key principles:** 1. Use `-r` for string output (raw, no quotes) 2. Use `.` notation for nested fields 3. Use `[]` for array access 4. Use `//` for defaults 5. Use `keys[]` for object properties 6. Pipe with `|` inside jq, pipe to shell after **Massive context savings: Extract only what is needed instead of reading entire JSON files.**