views:

11883

answers:

13

Is there a (*nix) command-line 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"
}

Thanks!

A: 

There is TidyJSON it's C#, so maybe you can get it to compile with Mono, and working on *nix. No guarantees though, sorry.

Robert Gould
+5  A: 
$ echo '{ "foo": "lorem", "bar": "ipsum" }' \
> | python -c'import fileinput, json;
> print(json.dumps(json.loads("".join(fileinput.input())),
>                  sort_keys=True, indent=4))'
{
    "bar": "ipsum",
    "foo": "lorem"
}

NOTE: It is not the way to do it.

The same in Perl:

$ cat json.txt \
> | perl -0007 -MJSON -nE'say to_json(from_json($_, {allow_nonref=>1}), 
>                                     {pretty=>1})'
{
   "bar" : "ipsum",
   "foo" : "lorem"
}
J.F. Sebastian
actually I do the same but with javascript itself :)
Robert Gould
+12  A: 

Thanks to J.F. Sebastian's very helpful pointers, here's a slightly enhanced script I've come up with:

#!/usr/bin/python

"""
Convert JSON data to human-readable form.

Usage:
  prettyJSON.py inputFile [outputFile]
"""

import sys
import simplejson as json


def main(args):
    try:
     inputFile = open(args[1])
     input = json.load(inputFile)
     inputFile.close()
    except IndexError:
     usage()
     return False
    if len(args) < 3:
     print json.dumps(input, sort_keys = False, indent = 4)
    else:
     outputFile = open(args[2], "w")
     json.dump(input, outputFile, sort_keys = False, indent = 4)
     outputFile.close()
    return True


def usage():
    print __doc__


if __name__ == "__main__":
    sys.exit(not main(sys.argv))
A: 

J.F. Sebastian's solutions didn't work for me in Ubuntu 8.04, here is a modified Perl version that works with the older 1.X JSON library:

perl -0007 -MJSON -ne 'print objToJson(jsonToObj($_, {allow_nonref=>1}), {pretty=>1}), "\n";'

pimlottc
+8  A: 

On *nix, reading from stdin and writing to stdout works better:

#!/usr/bin/env python
"""
Convert JSON data to human-readable form.

(Reads from stdin and writes to stdout)
"""

import sys
import simplejson as json


print json.dumps(json.loads(sys.stdin.read()), indent=4)
sys.exit(0)

Put this in a file (I named mine "prettyJSON" after AnC's answer) in your PATH and chmod +x it, and you're good to go.

Depending on the version of Python you have installed, you may need to replace "import simplejson as json" with "import json".

Daryl Spitzer
Indeed, using stdin/stdout is much more flexible and simple. Thanks for pointing it out.
AnC
For programs that expect a named file, use /dev/stdin, ditto for out and err.
A: 

I use json_xs to format/pretty-print json and yaml data.

Narcélio Filho
+7  A: 

for the peeps looking for a quick online thingy: http://www.shell-tools.net/index.php?op=json%5Fformat

Yannick Smits
+2  A: 

Or, with Ruby:

echo '{ "foo": "lorem", "bar": "ipsum" }' | ruby -r json -e 'jj JSON.parse gets'
Darscan
That gives me an error. Do you need some ruby json package installed?
mjs
Yes, you need the JSON Ruby Gem: sudo gem install json
Darscan
If you happen to be in ruby already just use `jj my_object`
matschaffer
+3  A: 

http://jsonlint.com has a nice validator/formatter if you not looking for a programmatic way of doing it.

knorthfield
+47  A: 

With python you can just do

echo '{"foo": "lorem", "bar": "ipsum"}' | python -mjson.tool
B Bycroft
I had no idea - thanks!
AnC
This seems to require python 2.6 (?).
mjs
Yes, Python 2.6 or higher is required.
Justin
+11  A: 

The JSON Ruby Gem is bundled with a shell script to prettify JSON:

sudo gem install json
echo '{ "foo": "bar" }' | prettify_json.rb
Paul Horsfall
A: 

with perl, use CPAN module JSON::XS.

it installs a command line tool "json_xs"

Validate:

json_xs -t null < myfile.json

Prettify the JSON file src.json to dst.json.

< src.json json_xs > pretty.json

knb
+4  A: 

I use JSON.stringify to pretty-print JSON.

Examples:

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

JSON.stringify({ foo: "lorem", bar: "ipsum" }, null, '\t');
Somu