How can I pretty-print JSON in a shell script?
With Python 2.6+ you can do:
echo '{"foo": "lorem", "bar": "ipsum"}' | python -m json.tool
or, if the JSON is in a file, you can do:
python -m json.tool my_json.json
if the JSON is from an internet source such as an API, you can use
curl http://my_url/ | python -m json.tool
For convenience in all of these cases you can make an alias:
alias prettyjson='python -m json.tool'
For even more convenience with a bit more typing to get it ready:
prettyjson_s() { echo "$1" | python -m json.tool}prettyjson_f() { python -m json.tool "$1"}prettyjson_w() { curl "$1" | python -m json.tool}
for all the above cases. You can put this in .bashrc
and it will be available every time in shell. Invoke it like prettyjson_s '{"foo": "lorem", "bar": "ipsum"}'
.
Note that as @pnd pointed out in the comments below, in Python 3.5+ the JSON object is no longer sorted by default. To sort, add the --sort-keys
flag to the end. I.e. ... | python -m json.tool --sort-keys
.
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 findtheir 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"
I use the "space" argument of JSON.stringify
to pretty-print JSON in JavaScript.
Examples:
// Indent with 4 spacesJSON.stringify({"foo":"lorem","bar":"ipsum"}, null, 4);// Indent with tabsJSON.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));\ });\"