Skip to content

Jq

← Back to all decks

30 cards — 🟢 4 easy | 🟡 9 medium | 🔴 7 hard

🟢 Easy (4)

1. How do you pretty-print a JSON file using jq?

Show answer Pipe it through jq with the identity filter: cat file.json | jq . (or jq . file.json). The dot (.) is the identity filter that outputs the input unchanged but formatted.

Example: curl -s https://api.github.com | jq . — instant pretty-printed JSON. Dot = identity filter.

2. What does the -r flag do in jq?

Show answer The -r (raw output) flag strips the surrounding double quotes from string output. Essential for using jq output in shell scripts and pipelines.

Example: without -r: '"John"'. With -r: 'John'. Essential: NAME=$(jq -r '.name' file.json)

3. How do you iterate over all elements of a JSON array in jq?

Show answer Use the .[] filter. For example, echo '[1,2,3]' | jq '.[]' outputs each element on its own line.

Remember: .[] iterates arrays AND objects. On objects, it outputs values (not keys). Use keys[] for keys.

Gotcha: .[] on an empty array produces no output (not null). Pipe to `length` first if you need to check.

4. How do you combine curl and jq to filter API responses in a pipeline?

Show answer curl -s https://api.example.com/items | jq '.results[] | {name: .name, status: .status}'. The -s flag silences curl progress. Pipe JSON output directly to jq for filtering. Add -f to curl to fail on HTTP errors, or use --fail-with-body (curl 7.76+) to still see the error response body.

🟡 Medium (9)

1. How do you filter JSON array elements by a condition using jq?

Show answer Use the select() function. For example: jq '.items[] | select(.status == "failed")' keeps only elements where status equals "failed".

Remember: select() keeps elements where the condition is true, drops the rest. Like SQL WHERE.

Example: jq '[.[] | select(.age > 30)]' wraps results back into an array. Without the outer [], you get bare values.

2. How do you apply a transformation to every element of a JSON array in jq?

Show answer Use the map() function. For example: jq 'map(.name)' extracts the name field from every object in the array, returning a new array of names.

Remember: map(f) = [.[] | f]. It is syntactic sugar for iterating and re-collecting into an array.

Gotcha: map() always returns an array. If you want bare values, use .[] | .name instead of map(.name).

3. What does jq's -s (slurp) mode do?

Show answer It reads all JSON inputs into a single array before applying the filter. Useful for combining multiple JSON lines (JSONL) into one array for sorting, counting, or aggregation.

Example: cat *.json | jq -s 'sort_by(.timestamp) | .[-1]' — combines JSONL, sorts, outputs latest.

4. How do you sum numeric values across JSON objects using jq?

Show answer Use reduce: jq 'reduce .[] as $item (0; . + $item.count)'. This initializes an accumulator at 0 and adds each item's count field.

Remember: reduce syntax: `reduce .[] as $item (INIT; UPDATE)`. INIT is the starting value, UPDATE is applied per element.

Analogy: reduce is jq's fold/accumulate — same concept as Python's functools.reduce or JavaScript's Array.reduce.

5. What does the alternative operator (//) do in jq, and when is it useful?

Show answer The // operator returns the right-hand value when the left is null or false: .name // "unknown". Essential for providing defaults when parsing JSON with optional fields, e.g., .config.timeout // 30.

Example: .timeout // 30 returns 30 if null. Chain: .x // .y // "default". Essential for optional fields.

6. How do you write an if-then-else expression in jq?

Show answer Syntax: if .status == "error" then "FAIL" elif .status == "warn" then "WARN" else "OK" end. The else clause is required. The expression returns a value — it does not branch control flow.

Example: if .status == "error" then "FAIL" else "OK" end — else is required. Returns a value.

7. What do the @base64, @csv, and @json format strings do in jq?

Show answer @base64 encodes a string to Base64 (decode with @base64d). @csv formats an array as a CSV row. @json re-serializes a value as a JSON string (useful for embedding JSON inside JSON). Use with -r for raw output.

8. How do you use jq path expressions to manipulate deeply nested JSON?

Show answer path(.a.b[].c) returns arrays of path segments. getpath(["a","b",0,"c"]) retrieves the value at that path. setpath(["a","b",0,"c"]; "new") sets it. Useful for programmatic traversal when the structure varies — you can iterate paths and transform values without hardcoding the nesting.

9. What is the difference between jq --arg and --argjson?

Show answer --arg name value passes value as a jq string ($name). --argjson name value parses value as JSON ($name can be a number, boolean, array, or object). Use --arg for string interpolation in filters; use --argjson when you need to compare against numbers or inject structured data.

🔴 Hard (7)

1. How do you construct a new JSON object from selected fields using jq?

Show answer Use object construction syntax: jq '{name: .metadata.name, status: .status.phase}'. This builds a new object with only the specified fields.

Example: jq '.items[] | {name: .metadata.name, cpu: .status.capacity.cpu}' — clean summaries from verbose JSON.

2. How do you build formatted strings using jq's string interpolation?

Show answer Use \() inside a quoted string with -r: jq -r '"\(.host):\(.port)"'. Parenthesized expressions are evaluated and inserted into the string.

Example: jq -r '"\(.name)\t\(.status)"' — tab-separated output for shell scripts without JSON objects.

3. How does yq relate to jq, and how do you convert YAML to JSON with it?

Show answer yq applies jq-like filter syntax to YAML files. Convert YAML to JSON with: yq -o json file.yaml. Edit YAML in place with: yq -i '.spec.replicas = 5' deployment.yaml.

Example: yq -i '.spec.replicas = 5' deployment.yaml — edit YAML in place. Same jq-like syntax for YAML.

4. How do you group JSON array elements by a field and count each group using jq?

Show answer Use group_by followed by map: jq 'group_by(.status) | map({status: .[0].status, count: length})'. group_by sorts and partitions the array into sub-arrays sharing the same key value.

Remember: group_by sorts first, then groups. Output is an array of arrays. Use map to transform each group.

Example: Count HTTP status codes: jq 'group_by(.status) | map({status: .[0].status, count: length})' — instant histogram.

5. What does the recursive descent operator (..) do in jq?

Show answer The .. operator recursively descends into all values of the input.
Example: jq '.. | .name? // empty' extracts every "name" field at any nesting depth. Useful for searching deeply nested or variable-structure JSON.

6. How do you handle errors gracefully in jq using try-catch?

Show answer Use try-catch: jq 'try (.items[] | .name) catch "parse error"'. The try expression evaluates the filter; if it fails, catch provides a fallback value. Without catch, try silently suppresses errors and produces no output.

7. How do you access environment variables inside jq filters?

Show answer Use env.VAR_NAME or $ENV.VAR_NAME.
Example: jq --null-input 'env.HOME' prints the HOME variable. $ENV is an object of all env vars: $ENV | keys lists them. Useful for parameterizing filters in CI/CD pipelines without --arg: jq '.version = env.BUILD_VERSION' config.json.