149

Currently, when I want to pretty-print a json file using jq, I use:

cat file.json | jq .

Yet I would expect for jq to accept a file name as argument without having to fallback on cat.

The man page says:

jq [options...] filter [files...]

... By default, jq reads a stream of JSON objects (whitespace separated) from stdin. One or more files may be specified, in which case jq will read input from those instead.

Yet running:

jq file.json

fails by throwing compile errors that the keys are not defined.

How am I supposed to add the file when running jq?

k0pernikus
  • 15,463

1 Answers1

220
jq . file.json

is what I was looking for. I didn't realize that the . is a filter and not a placeholder for the piped in content:

.

The absolute simplest (and least interesting) filter is .. This is a filter that takes its input and produces it unchanged as output.

And the man page makes it clear that the filter is a required argument.

k0pernikus
  • 15,463
  • 11
    To modify a file in place, use jq . file.json | sponge file.json (this requires sponge from moreutils) – Flimm Jun 08 '22 at 18:29
  • 2
    How is this different from jq . file.json > file.json? – Steve Anderson Oct 31 '22 at 18:43
  • 5
    @SteveAnderson - if a process opens a file, processes it line-by-line, and outputs each line, then the output pipe will clobber that file, potentially while it's in use. This is sometimes fine, but to be 100% certain it's OK, use sponge, which buffers. – Mark McDonald Nov 16 '22 at 04:21
  • This technically worked for me, but I don't know why it slowed my (relatively new w/ no other problems) computer down to nearly a standstill. File size was only 5kb. Maybe because it had Chinese characters in it? – Joe Flack Jan 17 '23 at 20:58
  • I had a large list of files I wanted to format in-place; thanks for the sponge reference, that helped a ton: find . -type f -exec sh -c 'jq . "{}"|sponge "{}"' \; – Joe Bane Oct 24 '23 at 16:00