Initial commit
This commit is contained in:
57
skills/jq/SKILL.md
Normal file
57
skills/jq/SKILL.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
name: jq
|
||||
description: Extract specific fields from JSON files efficiently using jq instead of reading entire files, saving 80-95% context.
|
||||
---
|
||||
|
||||
# jq: JSON Data Extraction Tool
|
||||
|
||||
Use jq to extract specific fields from JSON files without loading entire file contents into context.
|
||||
|
||||
## When to Use jq vs Read
|
||||
|
||||
**Use jq when:**
|
||||
- Need specific field(s) from structured data file
|
||||
- File is large (>50 lines) and only need subset
|
||||
- Querying nested structures
|
||||
- Filtering/transforming data
|
||||
- **Saves 80-95% context** vs reading entire file
|
||||
|
||||
**Just use Read when:**
|
||||
- File is small (<50 lines)
|
||||
- Need to understand overall structure
|
||||
- Making edits (need full context anyway)
|
||||
|
||||
## Common File Types
|
||||
|
||||
JSON files where jq excels:
|
||||
- package.json, tsconfig.json
|
||||
- Lock files (package-lock.json, yarn.lock in JSON format)
|
||||
- API responses
|
||||
- Configuration files
|
||||
|
||||
## Quick Examples
|
||||
|
||||
```bash
|
||||
# Get version from package.json
|
||||
jq -r .version package.json
|
||||
|
||||
# Get nested dependency version
|
||||
jq -r '.dependencies.react' package.json
|
||||
|
||||
# List all dependencies
|
||||
jq -r '.dependencies | keys[]' package.json
|
||||
```
|
||||
|
||||
## Core Principle
|
||||
|
||||
Extract exactly what is needed in one command - massive context savings compared to reading entire files.
|
||||
|
||||
## Detailed Reference
|
||||
|
||||
For comprehensive jq patterns, syntax, and examples, load [jq guide](./reference/jq-guide.md):
|
||||
- Core patterns (80% of use cases)
|
||||
- Real-world workflows
|
||||
- Advanced patterns
|
||||
- Pipe composition
|
||||
- Error handling
|
||||
- Integration with other tools
|
||||
361
skills/jq/reference/jq-guide.md
Normal file
361
skills/jq/reference/jq-guide.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# 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.**
|
||||
Reference in New Issue
Block a user