jq-yq
jq & yq
Command-line JSON and YAML processing.
jq Fundamentals
Extract Values
# Get field / nested field
echo '{"name":"John","age":30}' | jq '.name'
echo '{"user":{"name":"John"}}' | jq '.user.name'
# Array element
echo '[1,2,3]' | jq '.[0]'
# Multiple fields
echo '{"a":1,"b":2,"c":3}' | jq '{a,b}'
# Optional field access (no error if missing)
echo '{"a":1}' | jq '.b?'
Array Operations
# Iterate, filter, map
echo '[1,2,3]' | jq '.[]'
echo '[1,2,3,4,5]' | jq '[.[] | select(. > 2)]'
echo '[1,2,3]' | jq 'map(. * 2)'
# Length, first, last
echo '[1,2,3]' | jq 'length'
echo '[1,2,3]' | jq 'first'
# Flatten nested arrays
echo '[[1,2],[3,[4,5]]]' | jq 'flatten'
# Slice
echo '[10,20,30,40,50]' | jq '.[2:4]'
Object Arrays
# Extract, filter, sort
echo '[{"name":"a"},{"name":"b"}]' | jq '.[].name'
echo '[{"age":20},{"age":30}]' | jq '[.[] | select(.age > 25)]'
echo '[{"a":2},{"a":1}]' | jq 'sort_by(.a)'
# Group by field
echo '[{"type":"a","v":1},{"type":"b","v":2},{"type":"a","v":3}]' | jq 'group_by(.type)'
# Unique by field
echo '[{"id":1,"n":"a"},{"id":2,"n":"b"},{"id":1,"n":"c"}]' | jq 'unique_by(.id)'
# Min/max by field
echo '[{"score":80},{"score":95},{"score":72}]' | jq 'min_by(.score)'
Object Construction and Deconstruction
# Build new object with string interpolation
echo '{"first":"John","last":"Doe"}' | jq '{fullName: "\(.first) \(.last)"}'
# Add/delete/rename fields
echo '{"a":1}' | jq '. + {b:2}'
echo '{"a":1,"b":2}' | jq 'del(.b)'
echo '{"old":1}' | jq '{new: .old}'
# Flatten nested structure
echo '{"user":{"name":"Jo","addr":{"city":"NYC"}}}' | jq '{name: .user.name, city: .user.addr.city}'
# to_entries / from_entries (object <-> key-value pairs)
echo '{"a":1,"b":2}' | jq '[to_entries[] | {(.key): (.value * 10)}] | add'
# with_entries shorthand
echo '{"a":1,"b":2}' | jq 'with_entries(.value += 100)'
String Interpolation and Formatting
# Interpolation
echo '{"name":"Jo","age":30}' | jq -r '"Name: \(.name), Age: \(.age)"'
# Join / split
echo '["a","b","c"]' | jq 'join(", ")'
echo '"a,b,c"' | jq 'split(",")'
# Regex test and capture
echo '"hello"' | jq 'test("^hel")'
echo '"2024-01-15"' | jq 'capture("(?<y>[0-9]{4})-(?<m>[0-9]{2})-(?<d>[0-9]{2})")'
# {"y":"2024","m":"01","d":"15"}
Conditionals and Null Handling
# If-then-else
echo '{"age":20}' | jq 'if .age >= 18 then "adult" else "minor" end'
# Alternative operator (null coalescing)
echo '{"a":null}' | jq '.a // "default"'
# try-catch
echo '{"a":1}' | jq 'try .b.c.d catch "missing"'
# any/all
echo '[1,2,3]' | jq 'all(. > 0)'
Reduce and Aggregation
# Sum values
echo '[1,2,3,4,5]' | jq 'add'
# Reduce: accumulate a result
echo '[1,2,3,4,5]' | jq 'reduce .[] as $x (0; . + $x)'
# Build object from array
echo '[{"k":"a","v":1},{"k":"b","v":2}]' | jq 'reduce .[] as $item ({}; . + {($item.k): $item.v})'
# Group and aggregate
echo '[{"dept":"eng","sal":100},{"dept":"eng","sal":120},{"dept":"sales","sal":90}]' | \
jq 'group_by(.dept) | map({dept: .[0].dept, total: map(.sal) | add, count: length})'
Recursive Descent
# Find all values for a key at any depth
echo '{"a":{"name":"x","b":{"name":"y"}}}' | jq '.. | .name? // empty'
# Find all strings / numbers in a structure
echo '{"a":1,"b":"hello","c":{"d":"world"}}' | jq '[.. | strings]'
echo '{"a":1,"b":{"c":2},"d":[3,4]}' | jq '[.. | numbers]'
Output Flags and Format Encoders
# Raw output (no quotes) / compact output
echo '{"name":"John"}' | jq -r '.name'
echo '{"a":1}' | jq -c '.'
# Slurp multiple values into array
cat lines.json | jq -s '.'
# Raw input: treat each line as a string
echo -e "line1\nline2" | jq -R '.'
# Null input: generate JSON without input
jq -n '{created: now | todate}'
# TSV / CSV / URI encoding
echo '[{"n":"a","v":1},{"n":"b","v":2}]' | jq -r '.[] | [.n, .v] | @tsv'
echo '[{"n":"a","v":1},{"n":"b","v":2}]' | jq -r '.[] | [.n, .v] | @csv'
echo '{"q":"hello world"}' | jq -r '.q | @uri'
CSV/TSV Conversion
# JSON array of objects to CSV with header
echo '[{"name":"a","age":1},{"name":"b","age":2}]' | \
jq -r '(.[0] | keys_unsorted) as $k | $k, (.[] | [.[$k[]]])| @csv'
# CSV to JSON (line-by-line)
cat data.csv | jq -R 'split(",") | {id: .[0], name: .[1], value: .[2]}'
Environment Variable Integration
# Pass string variable into jq
NAME="John"
echo '{}' | jq --arg name "$NAME" '. + {name: $name}'
# Pass numeric / JSON value
echo '{}' | jq --argjson count 42 '. + {count: $count}'
TAGS='["a","b"]'
echo '{}' | jq --argjson tags "$TAGS" '. + {tags: $tags}'
# Access env directly
export MY_VAR="hello"
echo '{}' | jq -n 'env.MY_VAR'
yq YAML Processing
Read, Update, Delete
yq '.name' file.yaml
yq '.database.host' config.yaml
yq -i '.version = "2.0"' file.yaml
yq -i '.new_field = "value"' file.yaml
yq -i 'del(.unwanted)' file.yaml
yq 'keys' config.yaml
Select and Filter
yq '.items[] | select(.enabled == true)' config.yaml
yq '.services[] | select(has("port"))' config.yaml
yq 'select(.kind == "Service")' resources.yaml
yq '.spec.template.spec.containers[].image' deployment.yaml
Merge YAML Files
# Deep merge (second overrides first)
yq ea 'select(fileIndex == 0) * select(fileIndex == 1)' base.yaml override.yaml
# Merge all documents into one
yq ea '. as $item ireduce ({}; . * $item)' *.yaml
Convert Between Formats
yq -o=json file.yaml # YAML to JSON
yq -P file.json # JSON to YAML
yq -o=xml file.yaml # YAML to XML
yq -o=props file.yaml # YAML to properties
curl -s https://api.example.com/data | yq -P # pipe JSON to YAML
Multiple Documents
yq 'select(documentIndex == 0)' multi.yaml
yq 'select(documentIndex >= 0) | .metadata.namespace = "prod"' multi.yaml
yq ea '[.] | length' multi.yaml
Real-World Pipelines
API Response Processing with curl
# Get specific fields from API
curl -s 'https://api.github.com/repos/jqlang/jq/issues?per_page=5' | \
jq '[.[] | {number, title, state, user: .user.login}]'
# Paginate and collect
for page in $(seq 1 5); do
curl -s "https://api.example.com/items?page=$page"
done | jq -s 'map(.data[]) | flatten'
# Format as table
curl -s https://api.example.com/users | \
jq -r '.data[] | [.id, .name, .email] | @tsv' | column -t
Log Parsing
# Parse JSON log lines and filter errors
cat app.log | jq -R 'fromjson? | select(.level == "error")' 2>/dev/null
# Aggregate log levels
cat app.log | jq -R 'fromjson? | .level' 2>/dev/null | \
jq -s 'group_by(.) | map({level: .[0], count: length})'
Config File Manipulation
# Update version in package.json
jq '.version = "1.2.3"' package.json > tmp.$$ && mv tmp.$$ package.json
# Merge base and override configs
jq -s '.[0] * .[1]' base.json override.json > merged.json
# Bulk update scoped dependencies
jq '.dependencies |= with_entries(if .key | test("^@myorg/") then .value = "latest" else . end)' package.json
# Generate config from env vars
jq -n --arg host "$DB_HOST" --argjson port "${DB_PORT:-5432}" \
'{database: {host: $host, port: $port, ssl: true}}'
Kubernetes and Infrastructure
kubectl get pods -o json | jq -r '.items[].metadata.name'
kubectl get pods -o json | jq '.items[] | select(.status.phase != "Running") | .metadata.name'
yq -i '.spec.replicas = 3' deployment.yaml
Error Handling in Pipelines
# Try operator: skip errors silently
echo '[1,"two",3]' | jq '[.[] | try (. + 1)]'
# Validate JSON before processing
if echo "$data" | jq empty 2>/dev/null; then
echo "$data" | jq '.result'
else
echo "Invalid JSON"
fi
# Handle missing fields gracefully
echo '{"users":[{"name":"a"},{"email":"b@b.com"}]}' | \
jq '.users[] | {name: (.name // "unknown"), email: (.email // "none")}'
# -e flag: exit non-zero if result is false/null
curl -sf https://api.example.com/data | jq -e '.results | length > 0' > /dev/null
Performance: Streaming Large Files
# Stream parse: process without loading entire file into memory
jq --stream 'select(.[0][-1] == "name") | .[1]' huge.json
# Truncated stream: get first N matches efficiently
jq -c '.[]' huge_array.json | head -100 | jq -s '.'
# NDJSON: each line parsed independently, constant memory
cat large.ndjson | jq -c 'select(.status == "error")'
# Compare two large JSON files (sorted keys)
diff <(jq -S '.' a.json) <(jq -S '.' b.json)
Quick Reference
| Task | jq | yq |
|---|---|---|
| Pretty print | jq '.' |
yq '.' |
| Get field | jq '.key' |
yq '.key' |
| Filter | jq 'select(.x > 1)' |
yq 'select(.x > 1)' |
| Delete | jq 'del(.key)' |
yq 'del(.key)' |
| Merge | jq -s '.[0] * .[1]' |
yq ea '. as $i ireduce({}; . * $i)' |
| To JSON/YAML | -- | yq -o=json / yq -P |
| Raw output | jq -r |
yq -r |
| In-place | temp file or sponge |
yq -i |
More from 1mangesh1/dev-skills-collection
curl-http
HTTP request construction and API testing with curl and HTTPie. Use when user asks to "test API", "make HTTP request", "curl POST", "send request", "test endpoint", "debug API", "upload file", "check response time", "set auth header", "basic auth with curl", "send JSON", "test webhook", "check status code", "follow redirects", "rate limit testing", "measure API latency", "stress test endpoint", "mock API response", or any HTTP calls from the command line.
28database-indexing
Database indexing internals, index type selection, query plan analysis, and write-overhead tradeoffs across PostgreSQL, MySQL, and MongoDB. Use when user asks to "optimize queries", "create indexes", "fix slow queries", "read EXPLAIN output", "reduce query time", "index strategy", "database performance", "composite index", "covering index", "partial index", "index bloat", "unused indexes", or needs help diagnosing and resolving database performance problems.
13testing-strategies
Testing strategies, patterns, and methodologies across the full testing spectrum. Use when asked about unit tests, integration tests, e2e tests, test pyramid, mocking, test doubles, TDD, property-based testing, snapshot testing, test coverage, mutation testing, contract testing, performance testing, test data management, CI/CD testing, flaky tests, test anti-patterns, test organization, test isolation, test fixtures, test parameterization, or any testing strategy, approach, or methodology.
10mcp-setup
Model Context Protocol (MCP) server setup, configuration, and custom server development for Claude Code, Claude Desktop, Cursor, and VS Code. Use when asked to "setup MCP", "configure MCP server", "add MCP tools", "connect to MCP", "create MCP server", "build MCP tool", "debug MCP", "MCP transport", "MCP authentication", "MCP inspector", "list MCP servers", or integrate external tools via MCP protocol.
7authentication-patterns
Comprehensive authentication and authorization implementation guide. Use when the user asks about JWT tokens, OAuth 2.0 flows, session management, API key auth, SSO setup, SAML, OIDC, password hashing, multi-factor authentication, CSRF protection, token storage, CORS headers, rate limiting auth endpoints, bearer tokens, refresh tokens, OAuth scopes, identity providers, user permissions, role-based access control, attribute-based access control, or any authentication and authorization architecture, implementation, or security patterns.
6ssh-config
SSH key management, config file setup, tunnels, port forwarding, and jump hosts. Use when user asks to "setup SSH keys", "configure SSH", "create SSH tunnel", "add SSH host", "jump host", "port forwarding", "bastion host", "SSH agent", "ssh-copy-id", "SSH proxy", "SSH hardening", "SSH multiplexing", "SSH certificates", "multiple GitHub keys", "ProxyJump", "SSH debug", "SSH escape", "SSH SOCKS proxy", "rsync over SSH", or manage SSH connections.
6