Install
$ agentstack add skill-tangledgroup-tangled-skills-jq-1-8-2 ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
jq 1.8.2
Overview
jq is a lightweight, flexible command-line JSON processor written in C with zero runtime dependencies. Think of it as sed/awk/grep for JSON data. Version 1.8.2 includes significant security hardening (CVE fixes for buffer overflows, stack overflow guards, hash collision mitigation) and build improvements (Windows arm64, Docker arm/v7 support).
A jq program is a filter: it takes JSON input and produces JSON output. Filters chain with | (pipe), combine with , (comma), and support variables, conditionals, user-defined functions, regex, modules, and streaming.
Usage
Basic invocation
# Pretty-print / validate JSON
jq '.' file.json
# Extract a field
jq '.name' file.json
# Compact output (one JSON per line)
jq -c '.[]' file.json
# Raw string output (no quotes)
jq -r '.message' file.json
# NUL-delimited output (safe for filenames with newlines)
jq --raw-output0 '.path' file.json
# No newline after output
jq -j '.id' file.json
# Read from stdin
echo '{"a":1}' | jq '.a'
# Multiple files
jq '.name' file1.json file2.json
# Load filter from file
jq -f filter.jq data.json
# Pass string arguments
jq --arg name "Alice" '.name == $name' data.json
# Pass JSON arguments (parsed, not stringified)
jq --argjson age 30 '.age > $age' data.json
# Read a file as array of JSON values
jq --slurpfile config config.json '. + $config[0]' data.json
# Read raw file content as string
jq --rawfile tmpl template.html '$tmpl' null
# Environment variables
jq '$ENV.PATH' null
# Slurp all inputs into one array
jq -s 'map(.name)' file1.json file2.json
# Don't read input (use null as input, good for constructing JSON)
jq -n '{version: "1.0", items: [1,2,3]}'
# Raw input (each line becomes a string, not parsed as JSON)
jq -R 'split(",")' 18)'
jq '[.[] | select(.type == "user")]' # collect into array
# Map (apply filter to each element)
jq 'map(.name | ascii_upcase)'
jq 'map_values(.price * 0.9)' # same as map but preserves object shape
# Conditional
jq 'if .status == "ok" then .data else .error end'
# Alternative operator (//) — use right side if left is null or false
jq '.optional // "default"'
# Try-catch / error suppression
jq '.value? // 0' # ? suppresses errors
jq 'try .parse | catch "failed"'
# Variable binding
jq '.name as $n | select(.type == $n)'
# Reduce (fold array into single value)
jq '[.items[] | .price] | add / length' # average price
jq 'reduce .items[] as $item (0; . + $item.price)' # total price
# Group and sort
jq 'group_by(.category) | map({cat: .[0].category, count: length})'
jq 'sort_by(.date) | reverse'
# String interpolation
jq '"User \(.name) is \(.age) years old"'
# Regex operations
jq '.email | test("^[^@]+@[^@]+$")'
jq '.text | gsub("[0-9]"; "*")'
jq '.html | capture("(?.*)")'
# User-defined functions
jq 'def double: . * 2; [items[] | double]'
# Object construction / transformation
jq '{name, email}' # shorthand for {name: .name, email: .email}
jq '{(.key): .value}' # dynamic key from expression
jq '. + {"new_field": 42}' # merge objects (right wins on conflict)
jq '. * {"nested": {"a": 1}}' # recursive merge
# Type checking / conversion
jq 'select(type == "array")'
jq 'map(tostring)'
jq 'map(tonumber)'
Common patterns
# CSV to JSON (with headers)
jq -R -s 'split("\n") | .[1:] | map(split(",") | {name:.[0], age: (.[1]|tonumber)})' file.csv
# JSON to CSV
jq -r '[.name, .age] | @csv' file.json
# JSON to TSV
jq -r '[.name, .age] | @tsv' file.json
# JSON to XML (built-in format)
jq '@xml' file.json
# Base64 encode/decode
jq '.data | @base64' # encode
jq '"hello" | @base64d' # decode
# URL encoding
jq '.query | @uri' # encode
jq '"hello%20world" | @uri' # (already encoded, stays same)
# Date formatting
jq '.timestamp | strftime("%Y-%m-%d %H:%M:%S")'
# Construct JSON from scratch
jq -n '{users: [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]}'
# Merge two JSON files
jq -s '.[0] * .[1]' file1.json file2.json
# Filter array by multiple conditions
jq '[.[] | select(.active and .age >= 18 and (.role == "admin" or .role == "editor"))]'
# Unique values
jq '[.items[].tag] | unique'
# Count occurrences
jq 'group_by(.status) | map({status: .[0].status, count: length})'
# First/last/nth element
jq '.[0:1] | .[0]' # first
jq '.[-1:] | .[0]' # last
jq 'nth(5; .[])' # 6th element (0-indexed)
jq 'limit(10; .[])' # first 10 elements
# Deep path queries
jq 'paths(type == "string")' # paths to all string values
jq 'getpath(["user", "name"])' # same as .user.name
jq 'setpath(["user", "role"]; "admin")' # set nested value
jq 'del(.metadata.cache)' # delete a key
# Working with null
jq '.optional // empty' # produce no output if null/false
jq 'map(select(. != null))' # filter out nulls
Modules
# Import a module
# In your jq file: import "./mylib" as lib; lib.myfunc
# Include a module (functions become available directly)
# include "std"; my_builtin_func
# Specify library search path
jq -L ./lib -f program.jq data.json
Gotchas
- Always single-quote jq filters on Unix —
jq '.foo'notjq .foo. The shell interprets.,$,*,[], etc. as special characters. On Windows cmd.exe, use double quotes and escape inner double quotes. .fooonly works for identifier-like keys — keys with hyphens, spaces, or starting with digits need."key"or.["key"]syntax..in a pipeline refers to the current value at that point, not the original input. Useas $varto save the original.- Pipe is a cartesian product — if left side produces N results and right side produces M per result, you get N×M outputs, not N+M.
select(false)produces no output (notnull). Useselect(. != null)to filter nulls, or// emptyfor null/false suppression.//(alternative) triggers on bothnullANDfalse— if you only want null fallback, useif . == null then "default" else . end.?suppresses all errors, not just missing keys. Use carefully — it can hide real bugs.map(f)always returns an array;map_values(f)preserves the input type (array stays array, object stays object).- Numbers lose precision after arithmetic — jq stores literal numbers with original precision but converts to IEEE754 double on any operation. Use
have_decnumto check if your build supports arbitrary-precision decimals. - Object merge with
+is shallow — use*for recursive/ deep merge. group_byrequires sorted input — the array must be pre-sorted by the grouping key, or usesort_by(.key) | group_by(.key).recursecan infinite-loop on circular data. Userecurse(f; condition)to limit depth.- Regex requires Oniguruma support — check with
jq -n 'have("oniguruma")'. Most prebuilt binaries include it. inputsreads remaining JSON values from stdin/files after the first one (which is the normal input). Use with-nflag.--streamoutputs[path, value]pairs — you need to reconstruct the structure withreduce/foreachor usefromstream.- jq 1.8.2 limits array/object size to 2²⁹ elements and path depth for security. Deeply nested structures may hit these limits.
References
- [01-filters-and-operators](references/01-filters-and-operators.md) — Basic filters, operators, types, and values
- [02-builtin-functions](references/02-builtin-functions.md) — Complete list of built-in functions by category
- [03-conditionals-and-control-flow](references/03-conditionals-and-control-flow.md) — if-then-else, try-catch, select, reduce, foreach, while, until
- [04-regex](references/04-regex.md) — Regular expression functions: test, match, capture, scan, split, sub, gsub
- [05-advanced-features](references/05-advanced-features.md) — Variables, destructuring, def functions, scoping, generators, assignment operators
- [06-io-and-streaming](references/06-io-and-streaming.md) — input/inputs, debug, stderr, streaming parse, fromstream/tostream
- [07-modules](references/07-modules.md) — import, include, module declarations, library paths, modulemeta
- [08-cli-options](references/08-cli-options.md) — Complete command-line option reference with examples
- [09-formats-and-escaping](references/09-formats-and-escaping.md) — @csv, @tsv, @sh, @base64, @html, @json, @text, @uri, @xml, string interpolation
- [10-dates-and-math](references/10-dates-and-math.md) — Date/time functions, math library (sin, cos, exp, log, etc.)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: tangledgroup
- Source: tangledgroup/tangled-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.