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

匿名 (未验证) 提交于 2019-12-03 01:47:02

问题:

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" } 

回答1:

With Python 2.6+ you can just 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"}'.



回答2:

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.

Here is an example:

$ jq . 

Or in other words:

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


回答3:

I use the "space" argument of [JSON.stringify]1 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 nodejs, 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));\  });\ " 


回答4:

I wrote a tool that has one of the best "smart whitespace" formatters available. It produces more readable and less verbose output than most of the other options here.

underscore-cli

This is what "smart whitespace" looks like:

I may be a bit biased, but it's an awesome tool for printing and manipulating JSON data from the command-line. It's super-friendly to use and has extensive command-line help/documentation. It's a Swiss Army knife that I use for 1001 different small tasks that would be surprisingly annoying to do any other way.

Latest use-case: Chrome, Dev console, Network tab, export all as HAR file, "cat site.har | underscore select '.url' --outfmt text | grep mydomain"; now I have a chronologically ordered list of all URL fetches made during the loading of my company's site.

Pretty printing is easy:

underscore -i data.json print 

Same thing:

cat data.json | underscore print 

Same thing, more explicit:

cat data.json | underscore print --outfmt pretty 

This tool is my current passion project, so if you have any feature requests, there is a good chance I'll address them.



回答5:

I usually just do:

echo '{"test":1,"test2":2}' | python -mjson.tool 

And to retrieve select data (in this case, "test"'s value):

echo '{"test":1,"test2":2}' | python -c 'import sys,json;data=json.loads(sys.stdin.read()); print data["test"]' 

If the JSON data is in a file:

python -mjson.tool filename.json 

If you want to do it all in one go with curl on the command line using an authentication token:

curl -X GET -H "Authorization: Token wef4fwef54te4t5teerdfgghrtgdg53" http://testsite/api/ | python -mjson.tool 


回答6:

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:         if args[1] == '-':             inputFile = sys.stdin         else:             inputFile = open(args[1])         input = json.load(inputFile)         inputFile.close()     except IndexError:         usage()         return False     if len(args) 


回答7:

With Perl, use the CPAN module JSON::XS. It installs a command line tool json_xs.

Validate:

json_xs -t null 

Prettify the JSON file src.json to pretty.json:

 pretty.json 

If you don't have json_xs, try json_pp . "pp" is for "pure perl" – the tool is implemented in Perl only, without a binding to an external C library (which is what XS stands for, Perl's "Extension System").



回答8:

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 try:     import simplejson as json except:     import 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.



回答9:

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

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

Script download: gist.github.com/3738968



回答10:

If you use npm and Node.js, you can do npm install -g json and then pipe the command through json. Do json -h to get all the options. It can also pull out specific fields and colorize the output with -i.

curl -s http://search.twitter.com/search.json?q=node.js | json 


回答11:

UPDATE I'm using jq now as suggested in another answer. It's extremely powerful at filtering JSON, but, at its most basic, also an awesome way to pretty print JSON for viewing.

jsonpp is a very nice command line JSON pretty printer.

From the README:

Pretty print web service responses like so:

curl -s -L http://t.co/tYTq5Pu | jsonpp 

and make beautiful the files running around on your disk:

jsonpp data/long_malformed.json 

If you're on Mac OS X, you can brew install jsonpp. If not, you can simply copy the binary to somewhere in your $PATH.



回答12:

Try pjson. It has colors!

Install it with pip:

And then pipe any JSON content to pjson.



回答13:

It is not too simple with a native way with the jq tools.

For example:

cat xxx | jq . 


回答14:

I use jshon to do exactly what you're describing. Just run:

echo $COMPACTED_JSON_TEXT | jshon 

You can also pass arguments to transform the JSON data.



回答15:

Check out Jazor. It's a simple command line JSON parser written in Ruby.

gem install jazor jazor --help 


回答16:

$ 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" } 

Note 2: If you run

echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \ | python -c'import fileinput, json; print(json.dumps(json.loads("".join(fileinput.input())),                  sort_keys=True, indent=4))' 

the nicely readable word becomes \u encoded

{     "D\u00fcsseldorf": "lorem",      "bar": "ipsum" } 

If the remainder of your pipeline will gracefully handle unicode and you'd like your JSON to also be human-friendly, simply use ensure_ascii=False

echo '{ "Düsseldorf": "lorem", "bar": "ipsum" }' \ | python -c'import fileinput, json; print json.dumps(json.loads("".join(fileinput.input())),                  sort_keys=True, indent=4, ensure_ascii=False)' 

and you'll get:

{     "Düsseldorf": "lorem",      "bar": "ipsum" } 


回答17:

Or, with Ruby:

echo '{ "foo": "lorem", "bar": "ipsum" }' | ruby -r json -e 'jj JSON.parse gets' 


回答18:

Simply pipe the output to jq ..

Example:

twurl -H ads-api.twitter.com '.......' | jq . 


回答19:

JSONLint has an open-source implementation on github can be used on the command line or included in a node.js project.

npm install jsonlint -g 

and then

jsonlint -p myfile.json 

or

curl -s "http://api.twitter.com/1/users/show/user.json" | jsonlint | less 


回答20:

That's how I do it:

curl yourUri | json_pp 

It shortens the code and gets the job done.



回答21:

Pygmentize

I combine Python's json.tool with pygmentize:

echo '{"foo": "bar"}' | python -m json.tool | pygmentize -g 

There are some alternatives to pygmentize which are listed in my this answer.

Here is a live demo:



回答22:

I recommend using the json_xs command line utility which is included in the JSON::XS perl module. JSON::XS is a Perl module for serializing/deserializing JSON, on a Debian or Ubuntu machine you can install it like this:

sudo apt-get install libjson-xs-perl 

It is obviously also available on CPAN.

To use it to format JSON obtained from a URL you can use curl or wget like this:

$ curl -s http://page.that.serves.json.com/json/ | json_xs 

or this:

$ wget -q -O - http://page.that.serves.json.com/json/ | json_xs 

and to format JSON contained in a file you can do this:

$ json_xs 

To reformat as YAML, which some people consider to be more humanly-readable than JSON:

$ json_xs -t yaml 


回答23:

With Perl, if you install JSON::PP from CPAN you'll get the json_pp command. Stealing the example from B Bycroft you get:

[pdurbin@beamish ~]$ echo '{"foo": "lorem", "bar": "ipsum"}' | json_pp {    "bar" : "ipsum",    "foo" : "lorem" } 

It's worth mentioning that json_pp comes pre-installed with Ubuntu 12.04 (at least) and Debian in /usr/bin/json_pp



回答24:

  1. brew install jq
  2. command + | jq
  3. (example: curl localhost:5000/blocks | jq)
  4. Enjoy!



回答25:

Install yajl-tools with the command below:

sudo apt-get install yajl-tools

then,

echo '{"foo": "lorem", "bar": "ipsum"}' | json_reformat



回答26:

yajl is very nice, in my experience. I use its json_reformat command to pretty-print .json files in vim by putting the following line in my .vimrc:

autocmd FileType json setlocal equalprg=json_reformat 


回答27:

I'm using httpie

$ pip install httpie 

And you can use it like this

 $ http PUT localhost:8001/api/v1/ports/my   HTTP/1.1 200 OK  Connection: keep-alive  Content-Length: 93  Content-Type: application/json  Date: Fri, 06 Mar 2015 02:46:41 GMT  Server: nginx/1.4.6 (Ubuntu)  X-Powered-By: HHVM/3.5.1   {      "data": [],       "message": "Failed to manage ports in 'my'. Request body is empty",       "success": false  } 


回答28:

The PHP version, if you have PHP >= 5.4.

alias prettify_json=php -E '$o = json_decode($argn); print json_encode($o, JSON_PRETTY_PRINT);' echo '{"a":1,"b":2}' | prettify_json 


回答29:

I know this question has been replied ad nauseam, but I wanted to document a Ruby solution that is better than Json's prettify command, the gem colorful_json is fairly good.

gem install colorful_json echo '{"foo": "lorem", "bar": "ipsum"}' | cjson {   "foo": "lorem",   "bar": "ipsum" } 


回答30:

Use Ruby in one line:

echo '{"test":1,"test2":2}' | ruby -e "require 'json'; puts JSON.pretty_generate(JSON.parse(STDIN.read))" 

And you can set an alias for this:

alias to_j="ruby -e \"require 'json';puts JSON.pretty_generate(JSON.parse(STDIN.read))\"" 

Then you can use it more conveniently

echo '{"test":1,"test2":2}' | to_j  {   "test": 1,   "test2": 2 } 

And if you want display JSON with color, your can install awesome_print,

gem install awesome_print 

then

alias to_j="ruby -e \"require 'json';require 'awesome_print';ap JSON.parse(STDIN.read)\"" 

Try it!

echo '{"test":1,"test2":2, "arr":["aa","bb","cc"] }' | to_j 



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!