data
jq Filter, reshape and summarize JSON on the command line with jq's small expression language.
Version 1.8.2 · Updated 2026-10-14
A jq program is a filter: it takes each JSON input and emits zero or more JSON outputs. The examples assume an input such as {"team":"ops","members":[{"name":"Ada","age":36,"tags":["oncall"]}]}.
Running jq Command-line options # Option Effect -rPrint strings without JSON quotes -cOne compact JSON value per line -nStart from null instead of reading input -sRead every input into one array -RTreat each input line as a string -eExit 1 if the last output is false or null -SSort object keys in the output -jRaw output without trailing newlines --tab, --indent 4Choose the pretty-print indentation
Pass values in safely # jq --arg who "$USER" '.members[] | select(.name == $who)' team.json
jq --argjson limit 30 '.members[] | select(.age > $limit)' team.json
jq -n --rawfile body notes.txt '{text: $body}'
jq -n '$ENV.HOME'
--arg always binds a string; use --argjson for numbers, booleans or objects.
Exit status in scripts # Tip
if jq -e '.members | length > 0' team.json >/dev/null; then
echo "team has members"
fi
With -e, a run that produces no valid result at all exits with 4.
Reading values Paths and indexes # Filter Result .The whole input, pretty-printed .teamValue of one key .members[0].nameNested lookup .members[-1]Last array element .members[1:3]Array slice, end exclusive .["odd key"]Key that is not a plain identifier .team?Same lookup, but suppress type errors
Iterate and combine # .members[] # one output per element
.members[].name # names, one per line
.team, .members[0].age # comma emits both results
.members[] | .tags[] # pipe feeds each result onward
.. # every value, recursively
Defaults and missing data # .owner // "unassigned"
.members[].email // empty
try (.raw | fromjson) catch "bad payload"
a // b yields b when a produces only null, false or nothing.
Building output Construct new values # {team, count: (.members | length)}
{(.team): [.members[].name]}
[.members[] | {name, senior: (.age >= 40)}]
"\(.team) has \(.members | length) people"
{team} is shorthand for {team: .team}; a parenthesized key is computed. Ready-made JSON can go straight to curl --json .
Format strings # Filter Output @csvArray as a CSV row, strings quoted @tsvArray as a tab-separated row @shShell-quoted string or words @uriPercent-encoded text @base64, @base64dEncode or decode Base64 @json, @htmlJSON text or HTML-escaped text
Rows for spreadsheets # jq -r '.members[] | [.name, .age] | @csv' team.json
jq -r '"name\tage", (.members[] | [.name, .age] | @tsv)' team.json
Combine with -r, otherwise each row is printed as a quoted JSON string.
Strings and regular expressions String helpers # Filter Purpose split(",")String to array on a literal separator join("-")Array of strings to one string ltrimstr("v")Remove a prefix if present trimRemove surrounding whitespace startswith("api")Prefix test tostring, tonumberConvert between types
Regex functions # .name | test("^a"; "i")
.version | capture("(?<major>[0-9]+)\\.(?<minor>[0-9]+)")
.text | [scan("[0-9]+")]
.path | gsub("/+"; "/")
jq uses Oniguruma's Perl-style syntax, not POSIX ERE; backslashes are doubled inside JSON strings. See the regex sheet .
Dates # Note
now | todate
"2026-03-01T08:00:00Z" | fromdate
.ts | gmtime | strftime("%Y-%m-%d")
Date builtins work in UTC: fromdate reads ISO 8601 text, todate and gmtime take Unix seconds.
Related references