jq . data.json prints the file indented by two spaces, in color when the output is a terminal. . is jq’s identity filter: it passes the input through unchanged, and jq’s printer does the formatting. It reads from a pipe too: curl -s https://api.example.com/users/42 | jq ..
printf '%s' '{"name":"café","id":12345678901234567890,"tags":["api","ops"],"active":true,"manager":null}' > data.json
jq . data.json
{
"name": "café",
"id": 12345678901234567890,
"tags": [
"api",
"ops"
],
"active": true,
"manager": null
}
That’s jq 1.7.1, and the formatter below prints the same for that text with 2 spaces.
The flags you’ll want
jq -S . data.json # sort keys at every depth
jq -c . data.json # minify: {"name":"café","id":12345678901234567890,...}
jq --indent 4 . data.json # 4 spaces; jq allows at most 7
jq --tab . data.json # tabs
jq -a . data.json # escape non-ASCII: "caf\u00e9"
jq -r .name data.json # one string, without quotes: café
jq empty data.json # validate only: no output, non-zero exit if invalid
-S orders keys by code point and leaves arrays in their order, the same as Sort keys below. --indent 0 prints the same as -c.
Big numbers: check your version
jq 1.7 keeps the full precision of a number literal it doesn’t compute with, so the 20-digit id above survives. jq 1.6 converts every number to an IEEE 754 double first, and it’s still what Debian 12 and Ubuntu 22.04 install (Ubuntu 24.04 has 1.7.1). With nums.json holding {"price":1.10,"id":12345678901234567890,"big":1e1000,"exp":1e5}:
$ jq --version
jq-1.6
$ jq -c . nums.json
{"price":1.1,"id":12345678901234567000,"big":1.7976931348623157e+308,"exp":100000}
The same file through jq 1.7.1:
$ jq -c . nums.json
{"price":1.10,"id":12345678901234567890,"big":1E+1000,"exp":1E+5}
Even 1.7 rewrites exponents (1e5 becomes 1E+5), and any arithmetic goes through a double: jq '.id + 1' prints 12345678901234567000. The formatter below keeps every token as written, 1e5 included.
Gotchas
jq . data.json > data.jsonleaves an empty file: the shell truncates it before jq reads it. Write to a temporary file andmvit back.- A repeated key keeps its last value:
{"a":1,"a":2}prints as{"a":2}. - jq reports the position where its reader stopped, which can be past the mistake. For
{"name":"api","port":8080,}it reportsExpected another key-value pair at line 1, column 27; the formatter below saysTrailing comma before } at line 1, column 26, the comma itself. jq -e .sets the exit status from the output, so a file that holds onlynullorfalseexits 1. Usejq emptyto validate.