English 中文(简体)
我该如何在Shell脚本中美化JSON?
原标题:
  • 时间:2008-12-09 08:20:45
  •  标签:

有没有一种(Unix)shell脚本将JSON格式化为易于阅读的格式?

基本上,我想它将以下内容转化为:

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

把这个翻译成汉语,大致像这样:

{
    "foo": "lorem",
    "bar": "ipsum"
}
问题回答

使用Python 2.6+,您可以执行以下操作:

echo  {"foo": "lorem", "bar": "ipsum"}  | python -m json.tool

或者,如果JSON在文件中,您可以执行以下操作:

python -m json.tool my_json.json

如果JSON来自互联网源(例如API),您可以使用

curl http://my_url/ | python -m json.tool

为了方便,在所有这些情况下您可以创建一个别名:

alias prettyjson= python -m json.tool 

为了更加方便,需要多输入一点以准备好它:

prettyjson_s() {
    echo "$1" | python -m json.tool
}

prettyjson_f() {
    python -m json.tool "$1"
}

prettyjson_w() {
    curl "$1" | python -m json.tool
}

对于所有上述情况,您可以将其放入.bashrc中,在Shell中每次都可以使用。像这样调用它: prettyjson_s {"foo": "lorem", "bar": "ipsum"}

请注意,在Python 3.5+中,默认情况下不再按顺序排列JSON对象。要进行排序,请在末尾添加--sort-keys标志。例如:... | python -m json.tool --sort-keys

你可以使用: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.

用法示例:

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

或者使用带有身份过滤器的 jq:

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

我使用 JSON.stringify 的 "space" 参数在 JavaScript 中漂亮地打印 JSON。

例子:

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

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

使用 Node.js 的 Unix 命令行,指定 JSON 命令行:

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

退回:

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

从Unix命令行使用Node.js,指定包含JSON的文件名,并使用四个空格的缩进:

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

使用管道:

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

我写了一个工具,其中拥有一个最好的“智能空白符”格式化程序。它可以产生比这里的大多数其他选项更易读且不太冗长的输出。

underscore-cli (下划线命令行界面)

这就是“智能空白”的样子:

请将此翻译成中文: 无法翻译。这是一张图片。

我可能有点偏见,但它是一个从命令行打印和操纵JSON数据的绝妙工具。它使用起来非常友好,拥有广泛的命令行帮助/文档。它是一个瑞士军刀,我用它来完成1001个不同的小任务,在其他方式下都会非常烦人。

最新使用案例:Chrome,Dev控制台,网络选项卡,将所有内容导出为HAR文件,“cat site.har | underscore select .url --outfmt text | grep mydomain”;现在我拥有了一个按时间顺序排列的列表,其中包含了在加载我公司网站期间进行的所有URL获取。

漂亮打印很简单:

underscore -i data.json print

同样的事情。

cat data.json | underscore print

相同的事情,更明确:

cat data.json | underscore print --outfmt pretty

这个工具是我当前的热衷项目,如果你有任何特性请求,有很大的机会我会考虑实现它们。

我通常只是做:

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

取回特定数据(在这种情况下,“test”的值):

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

如果 JSON 数据在文件中:

python -mjson.tool filename.json

如果你想在命令行上使用身份验证令牌一次完成所有操作,请使用curl

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

如果您使用npm和Node.js,您可以执行npm install -g json,然后将命令通过json进行管道传输。 执行json -h以获取所有选项。它还可以提取特定的字段,并使用-i着色输出。

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

由于J.F.塞巴斯蒂安的非常有用的指示,这里是我提出的稍微增强的脚本:

#!/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) < 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))

使用jq工具的本地方式并不太简单。

例如:

cat xxx | jq .

一个用于漂亮打印JSON格式的简单Bash脚本

json_pretty.sh的翻译为:json_pretty.sh

#/bin/bash

grep -Eo  "[^"]*" *(: *([0-9]*|"[^"]*")[^{}["]*|,)?|[^"][}{]*|{|},?|[|],?|[0-9 ]*,?  | awk  {if ($0 ~ /^[}]]/ ) offset-=4; printf "%*c%s
", offset, " ", $0; if ($0 ~ /^[{[]/) offset+=4} 

例子:

cat file.json | json_pretty.sh的翻译为:json_pretty.sh

使用Perl,使用CPAN模块JSON::XS。它安装了一个命令行工具json_xs

验证:

json_xs -t null < myfile.json

将 JSON 文件 src.json 美化为 pretty.json:

< src.json json_xs > pretty.json

如果您没有json_xs,请尝试json_pp。 “pp”代表“纯 Perl”-该工具仅在Perl中实现,没有与外部C库的绑定(这就是XS代表的Perl“扩展系统”)。

在*nix上,从标准输入读入并写入标准输出能够更好地工作:

#!/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)

将这个放在一个文件中(我把它命名为“prettyJSON”,以致AnC的答案)放在你的路径下,然后chmod +x它,你就可以开始了。

那就是我做的方式:

curl yourUri | json_pp

它可以缩短代码并完成工作。

JSON Ruby Gem(宝石)已经捆绑了一个shell脚本来美化JSON:

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

脚本下载: gist.github.com/3738968 的翻译是: 脚本下载:gist.github.com/3738968

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

注意:这不是做事的方法。

在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)) 

易于阅读的单词变成了编码U。

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

如果您的流水线的剩余部分能够优雅地处理Unicode,并且您希望您的JSON也更加友好,只需使用 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"
}

更新:我现在正在使用另一个答案中建议的jq。它非常强大,可以过滤JSON,但最基本的也是一种非常棒的方法,用于查看JSON时漂亮地打印出来。

jsonpp是一个非常好用的命令行JSON格式化工具。

从自述文件:

美观的打印 Web 服务响应,如下所示:

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

美化您在磁盘上运行的文件:

jsonpp data/long_malformed.json

如果你使用 Mac OS X,你可以使用 brew install jsonpp 命令来安装。如果不是,你可以简单地将二进制文件复制到你的$PATH路径下的某个位置。

试试 pjson。它有颜色!

将此翻译成中文:echo  {"json":"obj"} | pjson 无法翻译该图像,因为它包含代码和特殊字符。

使用pip安装它:

⚡ pip install pjson

然后将任何 JSON 内容传输到 pjson

或者,使用 Ruby:

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

你可以使用这个简单的命令来实现结果:

echo "{ "foo": "lorem", "bar": "ipsum" }"|python -m json.tool

我使用 (http://kmkeen.com/jshon/)来完成您所描述的任务。只需运行:

echo $COMPACTED_JSON_TEXT | jshon

您还可以传递参数以转换JSON数据。

看一下Jazor。它是用Ruby编写的简单命令行JSON解析器。

gem install jazor
jazor --help

JSONLint在GitHub上有一个开源的实现,可用于命令行或包含在Node.js项目中。 JSONLint 在GitHub上有开源的实现可用于命令行或包含在Node.js项目中。

npm install jsonlint -g

然后 (ránhòu)

jsonlint -p myfile.json

或者

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

只需将输出管道传输到jq .

例子:

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

您可以简单地使用标准工具,如 jq 或 json_pp。

将其翻译成中文:echo { "foo": "l或者em", "bar": "ipsum" } | json_pp

或者

echo { "foo": "l或者em", "bar": "ipsum" } | jq

will both prettify output like the following (jq even m或者e col或者ful):

{
  "foo": "l或者em",
  "bar": "ipsum"
}

The huge advantage of jq is that it can do A LOT m或者e if you d like to parse and process the json.

你只需要使用jq

如果未安装jq,则需要先安装jq:

sudo apt-get update
sudo apt-get install jq

安装了jq后,只需要使用jq

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

输出看起来像

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

使用Perl,如果你从CPAN安装JSON::PP,你将得到json_pp命令。从B Bycroft借鉴示例,你可以获得:

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

值得一提的是,json_pp在Ubuntu 12.04(至少)和Debian中预装,在/usr/bin/json_pp中。

Pygmentize

我将 Python 的 json.tool 与 pygmentize 相结合。

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

以下是一些在我的回答中列出的代替pygmentize的选择。

这是现场演示:

把这个翻译成中文:示例

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 < file-full-of.json

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

$ json_xs -t yaml < file-full-of.json

jj is super-fast, can handle ginormous JSON documents economically, does not mess with valid JSON numbers, and is easy to use, e.g.

jj -p # for reading from STDIN

or

jj -p -i input.json

It is (2018) still quite new so maybe it won’t handle invalid JSON the way you expect, but it is easy to install on major platforms.

bat is a cat clone with syntax highlighting:

Example:

echo  {"bignum":1e1000}  | bat -p -l json

-p will output without headers, and -l will explicitly specify the language.

It has colouring and formatting for JSON and does not have the problems noted in this comment: How can I pretty-print JSON in a shell script?

Install yajl-tools with the command below:

sudo apt-get install yajl-tools

then,

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




相关问题
热门标签