# jq — Process JSON on the Command Line

> Practical guide to jq — filter, transform and query JSON on the command line with jq's expressive query language, from pretty-print to select().

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/jq/

<!-- PROSE:intro -->
jq is a lightweight, flexible JSON processor for the command line – you pipe JSON in from `curl`, `cat` or any other command and work with it the same way you already use `sed`, `awk` or `grep` for text. Instead of laboriously dissecting JSON with line-oriented tools, you use jq's own query language: filters you chain together with pipes `|`, field access via dot notation and `select()` for targeted filtering. With `-r` you emit raw strings without JSON quotes – perfect when you want to feed values into shell scripts. This guide walks you through the filters and patterns you actually reach for daily, from pretty-print to aggregating whole datasets.
<!-- PROSE:intro:end -->

## Basic Usage

`jq '.' <file>` — Pretty-print a JSON file with syntax highlighting.

```bash
jq '.' data.json
```

`cat <file> | jq '.'` — Pretty-print JSON from stdin (pipe from another command).

```bash
curl -s https://api.example.com/users | jq '.'
```

`jq -c '.' <file>` — Compact output — print JSON on a single line.

```bash
jq -c '.' data.json
```

`jq -r '.' <file>` — Raw output — print strings without JSON quotes (useful for shell scripts).

```bash
jq -r '.name' user.json
```

`jq -n '<expr>'` — Null input mode — evaluate an expression without reading any input.

```bash
jq -n '{name: "Alice", age: 30}'
```

`jq -s '.' <files>` — Slurp mode — read all inputs into an array instead of processing each line separately.

```bash
jq -s '.' a.json b.json
```

`jq -e '<filter>' <file>` — Exit with status 1 if the output is false or null. Useful in shell scripts.

```bash
jq -e '.active' user.json && echo 'User is active'
```

## Field Access & Paths

`jq '.<field>' <file>` — Access a top-level field by name.

```bash
jq '.name' user.json
```

`jq '.<field>.<nested>' <file>` — Access a nested field using dot notation.

```bash
jq '.address.city' user.json
```

`jq '.["<field>"]' <file>` — Access a field using bracket notation. Required for fields containing special characters or hyphens.

```bash
jq '["content-type"]' headers.json
```

`jq '.<field>?' <file>` — Optional field access — suppress errors if the field does not exist.

```bash
jq '.nickname?' user.json
```

`jq '.a, .b, .c' <file>` — Select multiple fields. Outputs each value on a separate line.

```bash
jq '.name, .email, .age' user.json
```

`jq 'path(..<field>)' <file>` — Return the path (as an array) to a field anywhere in the structure.

```bash
jq 'path(..id?)' data.json
```

## Array Operations

`jq '.[]' <file>` — Iterate over all elements of an array or values of an object.

```bash
jq '.[]' users.json
```

`jq '.[<n>]' <file>` — Access the element at index n (zero-based). Negative indices count from the end.

```bash
jq '.[0]' users.json
```

`jq '.[-1]' <file>` — Access the last element of an array.

```bash
jq '.[-1]' items.json
```

`jq '.[<from>:<to>]' <file>` — Slice an array from index 'from' (inclusive) to 'to' (exclusive).

```bash
jq '.[2:5]' items.json
```

`jq 'length' <file>` — Return the number of elements in an array, characters in a string, or keys in an object.

```bash
jq '.users | length' data.json
```

`jq 'first' <file>` — Return the first element produced by an expression.

```bash
jq 'first(.users[])' data.json
```

`jq 'last' <file>` — Return the last element produced by an expression.

```bash
jq 'last(.users[])' data.json
```

`jq 'reverse' <file>` — Reverse an array.

```bash
jq '.items | reverse' data.json
```

`jq 'flatten' <file>` — Flatten a nested array into a single-level array.

```bash
jq '.tags | flatten' data.json
```

`jq 'flatten(<depth>)' <file>` — Flatten a nested array to the specified depth.

```bash
jq '.nested | flatten(1)' data.json
```

`jq 'unique' <file>` — Remove duplicate values from an array.

```bash
jq '.tags | unique' data.json
```

`jq 'add' <file>` — Sum an array of numbers, concatenate strings, or merge an array of objects.

```bash
jq '.prices | add' cart.json
```

## Object Construction

`jq '{<key>: .<field>}' <file>` — Construct a new object with a specific key and value.

```bash
jq '{id: .id, username: .name}' user.json
```

`jq '{<field>}' <file>` — Shorthand: use field name as both key and value path.

```bash
jq '{name, email}' user.json
```

`jq '{(<expr>): <value>}' <file>` — Use a computed expression as an object key.

```bash
jq '{(.name): .score}' result.json
```

`jq '. + {<key>: <value>}' <file>` — Add or overwrite a field in an object using the merge operator.

```bash
jq '. + {active: true}' user.json
```

`jq 'del(.<field>)' <file>` — Remove a field from an object.

```bash
jq 'del(.password)' user.json
```

`jq 'del(.<field>, .<field2>)' <file>` — Remove multiple fields from an object.

```bash
jq 'del(.password, .token)' user.json
```

## Filtering & Select

`jq '.[] | select(.<field> == <value>)' <file>` — Filter array elements where a field equals a given value.

```bash
jq '.[] | select(.active == true)' users.json
```

`jq '.[] | select(.<field> > <n>)' <file>` — Filter elements where a numeric field exceeds a threshold.

```bash
jq '.[] | select(.age > 18)' users.json
```

`jq '.[] | select(.<field> | test("<regex>"))' <file>` — Filter elements where a string field matches a regular expression.

```bash
jq '.[] | select(.email | test("@gmail\.com$"))' users.json
```

`jq '.[] | select(.<field> != null)' <file>` — Filter elements where a field is not null (field exists and has a value).

```bash
jq '.[] | select(.phone != null)' users.json
```

`jq '.[] | select(has("<field>"))' <file>` — Filter elements that contain a specific key.

```bash
jq '.[] | select(has("avatar"))' users.json
```

`jq 'if <cond> then <a> else <b> end' <file>` — Conditional expression — return one value or another based on a condition.

```bash
jq 'if .active then "enabled" else "disabled" end' user.json
```

`jq '.<field> // <default>' <file>` — Alternative operator — use a default value if the result is null or false.

```bash
jq '.nickname // .name' user.json
```

## Transformation & Map

`jq 'map(<expr>)' <file>` — Apply an expression to every element of an array. Equivalent to [.[] | <expr>].

```bash
jq '.users | map(.name)' data.json
```

`jq 'map(select(<cond>))' <file>` — Filter an array to elements matching a condition (map + select).

```bash
jq '.users | map(select(.active == true))' data.json
```

`jq 'map_values(<expr>)' <file>` — Apply an expression to every value of an object or array.

```bash
jq 'map_values(. * 2)' scores.json
```

`jq '[.[] | <expr>]' <file>` — Collect results of an expression into a new array using array construction.

```bash
jq '[.items[] | .price]' cart.json
```

`jq '.[] | {<key>: .<field>}' <file>` — Transform each element of an array into a new object shape.

```bash
jq '.users[] | {id: .id, label: .name}' data.json
```

`jq '[.[] | {<key>: .<field>}]' <file>` — Transform an array into a new array of reshaped objects.

```bash
jq '[.users[] | {id: .id, label: .name}]' data.json
```

## Keys, Values & Entries

`jq 'keys' <file>` — Return a sorted array of an object's keys.

```bash
jq 'keys' config.json
```

`jq 'keys_unsorted' <file>` — Return an object's keys in their original insertion order.

```bash
jq 'keys_unsorted' config.json
```

`jq 'values' <file>` — Return an array of an object's values.

```bash
jq '.settings | values' config.json
```

`jq 'has("<key>")' <file>` — Return true if the object contains the given key, or the array has the given index.

```bash
jq 'has("email")' user.json
```

`jq 'in' <file>` — Return true if the left-hand value is a key in the right-hand object.

```bash
jq '.[] | in({"a":1, "b":2})' keys.json
```

`jq 'to_entries' <file>` — Convert an object to an array of {key, value} pairs.

```bash
jq '. | to_entries' config.json
```

`jq 'from_entries' <file>` — Convert an array of {key, value} pairs back into an object.

```bash
jq '. | from_entries' pairs.json
```

`jq 'with_entries(<expr>)' <file>` — Apply an expression to each {key, value} pair of an object. Shorthand for to_entries | map(<expr>) | from_entries.

```bash
jq 'with_entries(select(.value != null))' config.json
```

## Sorting, Grouping & Aggregation

`jq 'sort' <file>` — Sort an array of comparable values.

```bash
jq '.scores | sort' data.json
```

`jq 'sort_by(.<field>)' <file>` — Sort an array of objects by a specific field.

```bash
jq '.users | sort_by(.name)' data.json
```

`jq 'sort_by(.<field>) | reverse' <file>` — Sort an array by a field in descending order.

```bash
jq '.users | sort_by(.age) | reverse' data.json
```

`jq 'group_by(.<field>)' <file>` — Group an array of objects by the value of a specific field.

```bash
jq '.orders | group_by(.status)' data.json
```

`jq 'unique_by(.<field>)' <file>` — Remove duplicates from an array based on a specific field.

```bash
jq '.users | unique_by(.email)' data.json
```

`jq 'min_by(.<field>)' <file>` — Return the element with the minimum value for a given field.

```bash
jq '.products | min_by(.price)' data.json
```

`jq 'max_by(.<field>)' <file>` — Return the element with the maximum value for a given field.

```bash
jq '.products | max_by(.price)' data.json
```

`jq '[.[] | .<field>] | add' <file>` — Sum a numeric field across all elements of an array.

```bash
jq '[.items[] | .price] | add' cart.json
```

`jq 'reduce .[] as $x (0; . + $x)' <file>` — Reduce an array to a single value using an accumulator. Here: sum all numbers.

```bash
jq 'reduce .[] as $x (0; . + $x)' numbers.json
```

## String Operations

`jq 'test("<regex>")' <file>` — Return true if a string matches a regular expression.

```bash
jq '.email | test("@gmail\.com$")' user.json
```

`jq 'ascii_downcase' <file>` — Convert a string to lowercase.

```bash
jq '.name | ascii_downcase' user.json
```

`jq 'ascii_upcase' <file>` — Convert a string to uppercase.

```bash
jq '.status | ascii_upcase' item.json
```

`jq 'ltrimstr("<prefix>")' <file>` — Remove a prefix from a string if present.

```bash
jq '.url | ltrimstr("https://")' link.json
```

`jq 'rtrimstr("<suffix>")' <file>` — Remove a suffix from a string if present.

```bash
jq '.filename | rtrimstr(".json")' file.json
```

`jq 'startswith("<str>")' <file>` — Return true if the string starts with the given prefix.

```bash
jq '.url | startswith("https")' link.json
```

`jq 'endswith("<str>")' <file>` — Return true if the string ends with the given suffix.

```bash
jq '.filename | endswith(".json")' file.json
```

`jq 'split("<delim>")' <file>` — Split a string into an array on a delimiter.

```bash
jq '.tags | split(",")' item.json
```

`jq 'join("<delim>")' <file>` — Join an array of strings into a single string with a delimiter.

```bash
jq '.tags | join(", ")' item.json
```

`jq '"prefix \(.field) suffix"' <file>` — String interpolation — embed expressions inside a string using \(...).

```bash
jq '"Hello, \(.name)! You are \(.age) years old."' user.json
```

`jq '@base64' <file>` — Encode a string as Base64.

```bash
jq '.data | @base64' file.json
```

`jq '@base64d' <file>` — Decode a Base64-encoded string.

```bash
jq '.encoded | @base64d' file.json
```

`jq '@uri' <file>` — Percent-encode a string for use in URLs.

```bash
jq '.query | @uri' search.json
```

`jq '@csv' <file>` — Format an array as a CSV row string.

```bash
jq '.rows[] | @csv' data.json
```

`jq '@tsv' <file>` — Format an array as a tab-separated values (TSV) row string.

```bash
jq '.rows[] | @tsv' data.json
```

`jq '@html' <file>` — Escape special HTML characters (<, >, &, ', ") in a string.

```bash
jq '.body | @html' post.json
```

`jq '@sh' <file>` — Format a string or array as shell-escaped arguments.

```bash
jq '@sh "echo \(.name)"' user.json
```

## Types & Conversion

`jq 'type' <file>` — Return the JSON type of a value: null, boolean, number, string, array, or object.

```bash
jq '.value | type' data.json
```

`jq 'tostring' <file>` — Convert any value to its JSON string representation.

```bash
jq '.count | tostring' data.json
```

`jq 'tonumber' <file>` — Convert a string to a number.

```bash
jq '.price | tonumber' item.json
```

`jq 'not' <file>` — Negate a boolean value.

```bash
jq '.active | not' user.json
```

`jq 'infinite' <file>` — Produce the IEEE 754 infinity value.

```bash
jq -n 'infinite'
```

`jq 'nan' <file>` — Produce an IEEE 754 NaN value.

```bash
jq -n 'nan'
```

`jq 'isinfinite' <file>` — Return true if a number is infinite.

```bash
jq '.value | isinfinite' data.json
```

`jq 'isnan' <file>` — Return true if a value is NaN.

```bash
jq '.value | isnan' data.json
```

`jq 'isnormal' <file>` — Return true if a number is a normal finite number.

```bash
jq '.value | isnormal' data.json
```

## Recursive & Path Operations

`jq '.. | .<field>?'  <file>` — Recursively search all descendants for a specific field (recursive descent).

```bash
jq '.. | .id?' data.json
```

`jq '[paths]' <file>` — Return all paths in the JSON structure as arrays.

```bash
jq '[paths]' config.json
```

`jq '[leaf_paths]' <file>` — Return paths to all leaf (non-container) values.

```bash
jq '[leaf_paths]' config.json
```

`jq 'getpath(["<a>","<b>"])' <file>` — Get a value at a specific path given as an array.

```bash
jq 'getpath(["address","city"])' user.json
```

`jq 'setpath(["<a>","<b>"]; <value>)' <file>` — Set a value at a specific path given as an array.

```bash
jq 'setpath(["address","city"]; "Berlin")' user.json
```

`jq 'delpaths([["<a>"],["<b>"]])' <file>` — Delete values at multiple given paths.

```bash
jq 'delpaths([["password"],["token"]])' user.json
```

## Variables & Definitions

`jq '.<field> as $<var> | <expr>' <file>` — Assign a value to a named variable for reuse in a later expression.

```bash
jq '.total as $t | .items[] | {name, pct: (.price / $t * 100)}' data.json
```

`jq --arg <var> '<value>' '<expr>' <file>` — Pass a shell variable into jq as a string variable.

```bash
jq --arg name "Alice" '.[] | select(.name == $name)' users.json
```

`jq --argjson <var> '<json>' '<expr>' <file>` — Pass a shell variable into jq as a parsed JSON value.

```bash
jq --argjson minAge 18 '.[] | select(.age >= $minAge)' users.json
```

`jq 'def <name>: <body>; <expr>' <file>` — Define a reusable function inline.

```bash
jq 'def double: . * 2; .values[] | double' data.json
```

`jq -f <file.jq> <file>` — Read a jq filter from a file instead of a command-line argument.

```bash
jq -f transform.jq data.json
```

`jq 'env.<VAR>'` — Access an environment variable by name.

```bash
jq -n 'env.HOME'
```

`jq '$ENV.<VAR>'` — Access environment variables via the $ENV object.

```bash
jq -n '$ENV.PATH'
```

## Error Handling

`jq 'try <expr>' <file>` — Attempt an expression and suppress any errors it produces.

```bash
jq '.[] | try .value' mixed.json
```

`jq 'try <expr> catch <handler>' <file>` — Attempt an expression and run a handler if it fails. The error message is available as the input to the handler.

```bash
jq 'try tonumber catch "not a number"' values.json
```

`jq 'error("<message>")' <file>` — Raise a custom error and stop processing.

```bash
jq 'if .status != "ok" then error("unexpected status") else . end' resp.json
```

`jq '.[]?' <file>` — Iterate with the optional operator — suppress errors if the value is not iterable.

```bash
jq '.items[]?' data.json
```

## Practical Examples

`curl -s <api_url> | jq '.'` — Pretty-print a JSON API response.

```bash
curl -s https://api.github.com/users/octocat | jq '.'
```

`jq '.[] | select(.status == "active") | .name' <file>` — Extract names of all active users as plain strings (-r for raw output).

```bash
jq -r '.[] | select(.status == "active") | .name' users.json
```

`jq 'del(.[] | .password, .token)' <file>` — Remove sensitive fields from every object in an array.

```bash
jq 'del(.[] | .password, .token)' users.json
```

`jq '[.[] | {key: .id, value: .name}] | from_entries' <file>` — Convert an array of objects into a lookup map keyed by id.

```bash
jq '[.[] | {key: (.id|tostring), value: .name}] | from_entries' users.json
```

`jq 'group_by(.category) | map({category: .[0].category, count: length})' <file>` — Count items per category.

```bash
jq 'group_by(.category) | map({category: .[0].category, count: length})' items.json
```

`jq -r '[.name, .email, .age | tostring] | @csv' <file>` — Export selected fields as a CSV row.

```bash
jq -r '.[] | [.name, .email, (.age|tostring)] | @csv' users.json
```

`jq -s '.[0] * .[1]' <file1> <file2>` — Deep-merge two JSON objects (the * operator recursively merges objects).

```bash
jq -s '.[0] * .[1]' defaults.json overrides.json
```

`jq 'to_entries | map(select(.value == null)) | map(.key)' <file>` — Find all keys with null values in an object.

```bash
jq 'to_entries | map(select(.value == null)) | map(.key)' config.json
```

`jq -r 'path(..)|map(tostring)|join(".")' <file>` — Print all key paths in dot notation (useful for exploring deep structures).

```bash
jq -r '[path(..)|map(tostring)|join(".")]|unique[]' config.json
```

`jq -R 'split(" ") | {method: .[0], path: .[1], status: .[2]}' <file>` — Parse plain-text lines into JSON objects (-R reads raw strings as input).

```bash
jq -R 'split(" ") | {method: .[0], path: .[1]}' access.log
```

<!-- PROSE:outro -->
## Conclusion

jq is read-only and therefore safe by design – it reads JSON but never alters your source file, writing the result to standard output instead. For everyday work a handful of building blocks gets you far: `.field` for access, `|` for chaining, `select()` for filtering and `map()` for transformation. Take care with raw output via `-r`: as soon as you feed the values back into the shell, you are responsible for correct quoting yourself, because spaces, newlines or special characters in the data can otherwise break your script. And treat JSON from untrusted sources with the same scepticism as any other foreign input – validate the structure before you rely on specific fields.

## Further Reading

- [jq manual](https://jqlang.github.io/jq/manual/) – the official, complete reference for the jq query language
- [jq on Wikipedia](https://en.wikipedia.org/wiki/Jq_(programming_language)) – overview of the history and use of jq
- [jq play](https://jqplay.org/) – interactive playground to try out jq filters right in your browser
<!-- PROSE:outro:end -->

## Related Commands

- [yq](https://www.jpkc.com/db/en/cheatsheets/files-text/yq/) – jq-style processor for YAML and JSON
- [grep](https://www.jpkc.com/db/en/cheatsheets/files-text/grep/) – search text files line by line with patterns
- [sed](https://www.jpkc.com/db/en/cheatsheets/files-text/sed/) – stream editor for search-and-replace in text

