[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-b69d1001-26c7-4c31-b6c8-605e04ab6488":3,"$fcvwcPIyvsgnh7dr_h0GWaUQ0ovMspEH3VLLo-JGdGvY":43},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":34},"b69d1001-26c7-4c31-b6c8-605e04ab6488","jq","JSON查询、过滤、转换和管道集成的高级jq使用。实际shell工作流程的实用模式。","cat_life_career","mod_other","sickn33,other","---\nname: jq\ndescription: \"Expert jq usage for JSON querying, filtering, transformation, and pipeline integration. Practical patterns for real shell workflows.\"\ncategory: development\nrisk: safe\nsource: community\ndate_added: \"2026-03-28\"\nauthor: kostakost2\ntags: [jq, json, shell, cli, data-transformation, bash]\ntools: [claude, cursor, gemini]\n---\n\n# jq — JSON Querying and Transformation\n\n## Overview\n\n`jq` is the standard CLI tool for querying and reshaping JSON. This skill covers practical, expert-level usage: filtering deeply nested data, transforming structures, aggregating values, and composing `jq` into shell pipelines. Every example is copy-paste ready for real workflows.\n\n## When to Use This Skill\n\n- Use when parsing JSON output from APIs, CLI tools (AWS, GitHub, kubectl, docker), or log files\n- Use when transforming JSON structure (rename keys, flatten arrays, group records)\n- Use when the user needs `jq` inside a bash script or one-liner\n- Use when explaining what a complex `jq` expression does\n\n## How It Works\n\n`jq` takes a filter expression and applies it to JSON input. Filters compose with pipes (`|`), and `jq` handles arrays, objects, strings, numbers, booleans, and `null` natively.\n\n### Basic Selection\n\n```bash\n# Extract a field\necho '{\"name\":\"alice\",\"age\":30}' | jq '.name'\n# \"alice\"\n\n# Nested access\necho '{\"user\":{\"email\":\"a@b.com\"}}' | jq '.user.email'\n\n# Array index\necho '[10, 20, 30]' | jq '.[1]'\n# 20\n\n# Array slice\necho '[1,2,3,4,5]' | jq '.[2:4]'\n# [3, 4]\n\n# All array elements\necho '[{\"id\":1},{\"id\":2}]' | jq '.[]'\n```\n\n### Filtering with `select`\n\n```bash\n# Keep only matching elements\necho '[{\"role\":\"admin\"},{\"role\":\"user\"},{\"role\":\"admin\"}]' \\\n  | jq '[.[] | select(.role == \"admin\")]'\n\n# Numeric comparison\ncurl -s https:\u002F\u002Fapi.github.com\u002Frepos\u002Fowner\u002Frepo\u002Fissues \\\n  | jq '[.[] | select(.comments > 5)]'\n\n# Test a field exists and is non-null\njq '[.[] | select(.email != null)]'\n\n# Combine conditions\njq '[.[] | select(.active == true and .score >= 80)]'\n```\n\n### Mapping and Transformation\n\n```bash\n# Extract a field from every array element\necho '[{\"name\":\"alice\",\"age\":30},{\"name\":\"bob\",\"age\":25}]' \\\n  | jq '[.[] | .name]'\n# [\"alice\", \"bob\"]\n\n# Shorthand: map()\njq 'map(.name)'\n\n# Build a new object per element\njq '[.[] | {user: .name, years: .age}]'\n\n# Add a computed field\njq '[.[] | . + {senior: (.age > 28)}]'\n\n# Rename keys\njq '[.[] | {username: .name, email_address: .email}]'\n```\n\n### Aggregation and Reduce\n\n```bash\n# Sum all values\necho '[1, 2, 3, 4, 5]' | jq 'add'\n# 15\n\n# Sum a field across objects\njq '[.[].price] | add'\n\n# Count elements\njq 'length'\n\n# Max \u002F min\njq 'max_by(.score)'\njq 'min_by(.created_at)'\n\n# reduce: custom accumulator\necho '[1,2,3,4,5]' | jq 'reduce .[] as $x (0; . + $x)'\n# 15\n\n# Group by field\njq 'group_by(.department)'\n\n# Count per group\njq 'group_by(.status) | map({status: .[0].status, count: length})'\n```\n\n### String Interpolation and Formatting\n\n```bash\n# String interpolation\njq -r '.[] | \"\\(.name) is \\(.age) years old\"'\n\n# Format as CSV (no header)\njq -r '.[] | [.name, .age, .email] | @csv'\n\n# Format as TSV\njq -r '.[] | [.name, .score] | @tsv'\n\n# URL-encode a value\njq -r '.query | @uri'\n\n# Base64 encode\njq -r '.data | @base64'\n```\n\n### Working with Keys and Paths\n\n```bash\n# List all top-level keys\njq 'keys'\n\n# Check if key exists\njq 'has(\"email\")'\n\n# Delete a key\njq 'del(.password)'\n\n# Delete nested keys from every element\njq '[.[] | del(.internal_id, .raw_payload)]'\n\n# Recursive descent: find all values for a key anywhere in tree\njq '.. | .id? \u002F\u002F empty'\n\n# Get all leaf paths\njq '[paths(scalars)]'\n```\n\n### Conditionals and Error Handling\n\n```bash\n# if-then-else\njq 'if .score >= 90 then \"A\" elif .score >= 80 then \"B\" else \"C\" end'\n\n# Alternative operator: use fallback if null or false\njq '.nickname \u002F\u002F .name'\n\n# try-catch: skip errors instead of halting\njq '[.[] | try .nested.value catch null]'\n\n# Suppress null output with \u002F\u002F empty\njq '.[] | .optional_field \u002F\u002F empty'\n```\n\n### Practical Shell Integration\n\n```bash\n# Read from file\njq '.users' data.json\n\n# Compact output (no whitespace) for further piping\njq -c '.[]' records.json | while IFS= read -r record; do\n  echo \"Processing: $record\"\ndone\n\n# Pass a shell variable into jq\nSTATUS=\"active\"\njq --arg s \"$STATUS\" '[.[] | select(.status == $s)]'\n\n# Pass a number\njq --argjson threshold 42 '[.[] | select(.value > $threshold)]'\n\n# Slurp multiple JSON lines into an array\njq -s '.' records.ndjson\n\n# Multiple files: slurp all into one array\njq -s 'add' file1.json file2.json\n\n# Null-safe pipeline from a command\nkubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'\n\n# GitHub CLI: extract PR numbers\ngh pr list --json number,title | jq -r '.[] | \"\\(.number)\\t\\(.title)\"'\n\n# AWS CLI: list running instance IDs\naws ec2 describe-instances \\\n  | jq -r '.Reservations[].Instances[] | select(.State.Name==\"running\") | .InstanceId'\n\n# Docker: show container names and images\ndocker inspect $(docker ps -q) | jq -r '.[] | \"\\(.Name)\\t\\(.Config.Image)\"'\n```\n\n### Advanced Patterns\n\n```bash\n# Transpose an object of arrays to an array of objects\n# Input: {\"names\":[\"a\",\"b\"],\"scores\":[10,20]}\njq '[.names, .scores] | transpose | map({name: .[0], score: .[1]})'\n\n# Flatten one level\njq 'flatten(1)'\n\n# Unique by field\njq 'unique_by(.email)'\n\n# Sort, deduplicate and re-index\njq '[.[] | .name] | unique | sort'\n\n# Walk: apply transformation to every node recursively\njq 'walk(if type == \"string\" then ascii_downcase else . end)'\n\n# env: read environment variables inside jq\nexport API_KEY=secret\njq -n 'env.API_KEY'\n```\n\n## Best Practices\n\n- Always use `-r` (raw output) when passing `jq` results to shell variables or other commands to strip JSON string quotes\n- Use `--arg` \u002F `--argjson` to inject shell variables safely — never interpolate shell variables directly into filter strings\n- Prefer `map(f)` over `[.[] | f]` for readability\n- Use `-c` (compact) for newline-delimited JSON pipelines; omit it for human-readable debugging\n- Test filters interactively with `jq -n` and literal input before embedding in scripts\n- Use `empty` to drop unwanted elements rather than filtering to `null`\n\n## Security & Safety Notes\n\n- `jq` is read-only by design — it cannot write files or execute commands\n- Avoid embedding untrusted JSON field values directly into shell commands; always quote or use `--arg`\n\n## Common Pitfalls\n\n- **Problem:** `jq` outputs `null` instead of the expected value\n  **Solution:** Check for typos in key names; use `keys` to inspect actual field names. Remember JSON is case-sensitive.\n\n- **Problem:** Numbers are quoted as strings in the output\n  **Solution:** Use `--argjson` instead of `--arg` when injecting numeric values.\n\n- **Problem:** Filter works in the terminal but fails in a script\n  **Solution:** Ensure the filter string uses single quotes in the shell to prevent variable expansion. Example: `jq '.field'` not `jq \".field\"`.\n\n- **Problem:** `add` returns `null` on an empty array\n  **Solution:** Use `add \u002F\u002F 0` or `add \u002F\u002F \"\"` to provide a fallback default.\n\n- **Problem:** Streaming large files is slow\n  **Solution:** Use `jq --stream` or switch to `jstream`\u002F`gron` for very large files.\n\n## Related Skills\n\n- `@bash-pro` — Wrapping jq calls in robust shell scripts\n- `@bash-linux` — General shell pipeline patterns\n- `@github-automation` — Using jq with GitHub CLI JSON output\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.\n","","imported","https:\u002F\u002Fgithub.com\u002Fsickn33\u002Fantigravity-awesome-skills","user_system_seed","SkillOPIC",true,188,564,"2026-05-16 13:24:35",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"其他","other","mdi-page-next-outline","其他类型Skill",5,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":32,"skillCount":33,"createdAt":26},"职场发展","career","mdi-briefcase-outline","面试准备、简历优化、职业规划",4,575,[35],{"id":36,"skillId":4,"version":37,"fileName":38,"fileSize":39,"filePath":40,"fileHash":41,"manifest":42,"createdAt":19},"4836003a-3580-4d74-befa-80b25313ae85","1.0.0","jq.zip",3642,"uploads\u002Fskills\u002Fb69d1001-26c7-4c31-b6c8-605e04ab6488\u002Fjq.zip","afeedb51c953cdd229db8175a0ab78d18fcdd555a99a8aba8a6ed0dff5ff4f79","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":7734}]",{"code":44,"message":45,"data":46},200,"success",{"items":47,"stats":48,"page":51},[],{"averageRating":49,"totalRatings":49,"ratingCounts":50},0,[49,49,49,49,49],{"limit":52,"offset":49,"hasMore":53,"nextOffset":52,"ratedOnly":16},15,false]