Categories
command-line format json pretty-print unix

How can I pretty-print JSON in a shell script?

3466

Is there a (Unix) shell script to format JSON in human-readable form?

Basically, I want it to transform the following:

{ "foo": "lorem", "bar": "ipsum" }

… into something like this:

{
    "foo": "lorem",
    "bar": "ipsum"
}

12

  • 10

    I rolled my own a short while back: github.com/exhuma/braindump/tree/master/jsonformat The code is very simple, using python’s own json library, but I added pygments as well to get syntax highlighting.

    – exhuma

    Nov 9, 2012 at 13:40

  • Stumbled on to this but then found Json Pretty and I quite like it. Typekit uses it in their API examples, so there’s some klout behind it ^^

    Nov 21, 2012 at 14:42

  • If you don’t mind copying pasting, there’s also some simple tools online like jsonprettyprint.net where you can quickly pretty print your raw JSON.

    – Javaaaa

    Nov 9, 2014 at 16:56


  • 12

    Be warned: python -m json.tool does not always produce valid JSON. (Hint: 1e1000)

    – peak

    Sep 11, 2015 at 16:48

1373

You can use: jq

It’s very simple to use and it works great! It can handle very large JSON structures, including streams. You can find
their tutorials here.

Usage examples:

$ jq --color-output . file1.json file1.json | less -R

$ command_with_json_output | jq .

$ jq # stdin/"interactive" mode, just enter some JSON

$ jq <<< '{ "foo": "lorem", "bar": "ipsum" }'
{
  "bar": "ipsum",
  "foo": "lorem"
}

Or use jq with identity filter:

$ jq '.foo' <<< '{ "foo": "lorem", "bar": "ipsum" }'
"lorem"

18

  • 15

    There is also a --sort-keys option, which is helpful in some cases.

    Nov 4, 2014 at 1:17

  • 20

    Working with curl: curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.'

    Apr 21, 2015 at 7:44

  • 28

    “jq .” is great as a pretty-printer, but it comes with a caveat: jq (up to and including jq version 1.5) will alter the values of very large and very small numbers because it parses numeric values as IEEE 754 64-bit values. To check whether your favorite pretty-printer has the same issue, try this value: 1e1000. Note that python -mjson.tool fails this test badly in that it produces Infinity, which is not even JSON.

    – peak

    Sep 4, 2015 at 2:38


  • 28

    @Meekohi the alternative is “unnecessary use of echo”. Super happy to have found the <<< operator – exactly what I was looking for.

    – jchook

    Dec 28, 2016 at 20:10

  • 4

    jq is the best because it prints in colors!

    – phil294

    Jan 13, 2018 at 23:07

402

I use the “space” argument of JSON.stringify to pretty-print JSON in JavaScript.

Examples:

// Indent with 4 spaces
JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, 4);

// Indent with tabs
JSON.stringify({"foo":"lorem","bar":"ipsum"}, null, '\t');

From the Unix command-line with Node.js, specifying JSON on the command line:

$ node -e "console.log(JSON.stringify(JSON.parse(process.argv[1]), null, '\t'));" \
  '{"foo":"lorem","bar":"ipsum"}'

Returns:

{
    "foo": "lorem",
    "bar": "ipsum"
}

From the Unix command-line with Node.js, specifying a filename that contains JSON, and using an indent of four spaces:

$ node -e "console.log(JSON.stringify(JSON.parse(require('fs') \
      .readFileSync(process.argv[1])), null, 4));"  filename.json

Using a pipe:

echo '{"foo": "lorem", "bar": "ipsum"}' | node -e \
"\
 s=process.openStdin();\
 d=[];\
 s.on('data',function(c){\
   d.push(c);\
 });\
 s.on('end',function(){\
   console.log(JSON.stringify(JSON.parse(d.join('')),null,2));\
 });\
"

10

  • 10

    For debugging objects in Node.js, you should really use sys.inspect() instead of JSON.stringify(). Here’s why: markhansen.co.nz/inspecting-with-json-stringify

    Aug 11, 2011 at 18:05

  • 12

    Downvoted. The OP is about a “*nix command-line script” and this answer is a different context.

    – danorton

    Sep 2, 2012 at 14:30

  • 53

    @danorton: JS can be used from the commandline via node.js and other similar solutions.

    – calvinf

    Sep 17, 2012 at 20:08

  • 11

    No need for the console: node -p "JSON.stringify(JSON.parse(process.argv[1]), null, '\t');" also outputs the result to STDOUT.

    – Julian D.

    Nov 5, 2014 at 16:26

  • 3

    It sucks that the script is different for a filename vs. stdin

    Feb 17, 2016 at 13:39