【问题标题】:How can I pretty-print JSON in a shell script?如何在 shell 脚本中漂亮地打印 JSON?
【发布时间】:2010-09-26 00:15:08
【问题描述】:

是否有 (Unix) shell 脚本可以将 JSON 格式化为人类可读的格式?

基本上,我希望它转换以下内容:

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

...变成这样的:

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

【问题讨论】:

  • 不久前我推出了自己的代码:github.com/exhuma/braindump/tree/master/jsonformat 代码非常简单,使用 python 自己的 json 库,但我还添加了 pygments 以获得语法高亮。
  • 偶然发现了这个,但后来找到了Json Pretty,我非常喜欢它。 Typekit 在他们的 API 示例中使用它,所以它背后有一些 klout ^^
  • 如果您不介意复制粘贴,也有一些简单的在线工具,例如 jsonprettyprint.net,您可以在其中快速漂亮地打印原始 JSON。
  • 警告:python -m json.tool 并不总是产生有效的 JSON。 (提示:1e1000)

标签: json unix command-line format pretty-print


【解决方案1】:

当您在系统上安装了节点后,以下工作。

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

{
  "test": 1,
  "test2": 2
}

【讨论】:

    【解决方案2】:

    在一行中使用 Ruby:

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

    您可以为此设置别名:

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

    那么你可以更方便地使用它

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

    如果你想用颜色显示JSON,你可以安装awesome_print

    gem install awesome_print
    

    然后

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

    试试吧!

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

    【讨论】:

      【解决方案3】:

      使用 Node.js 的单行解决方案如下所示:

      $ node -e "console.log( JSON.stringify( JSON.parse(require('fs').readFileSync(0) ), 0, 1 ))"
      

      例如:

      $ cat test.json | node -e "console.log( JSON.stringify( JSON.parse(require('fs').readFileSync(0) ), 0, 1 ))"
      

      【讨论】:

      • 这个例子对我来说没有输出,即使我很久以前就投票了。发生了一些变化......
      • @MatthisKohli:我刚刚在 Node V12.x 上重新检查了它,它正在工作。这段代码没有什么神奇之处。 fs.readFileSync(0) 读取当前进程的 stdinJSON.stringify 格式化 JSON。因此,破坏 API 更改的机会非常少
      【解决方案4】:

      yajl 非常好,以我的经验。我使用它的json_reformat 命令在vim 中漂亮地打印.json 文件,方法是将以下行放入我的.vimrc

      autocmd FileType json setlocal equalprg=json_reformat
      

      【讨论】:

        【解决方案5】:

        这里有一个比 Json 的 prettify 命令更好的 Ruby 解决方案。宝石colorful_json 还算不错。

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

        【讨论】:

          【解决方案6】:

          我正在使用httpie

          $ pip install httpie
          

          你可以这样使用它

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

          【讨论】:

            【解决方案7】:

            PHP 版本,如果您有 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
            

            【讨论】:

            • 一个班轮:echo '{"a":1,"b":2}' | php -r 'echo json_encode(json_decode(fgets(STDIN)), JSON_PRETTY_PRINT)."\n";'
            • 支持多行:printf '{\n"a":1,\n"b":2\n}' | php -r 'echo json_encode(json_decode(file_get_contents("php://stdin")), JSON_PRETTY_PRINT) . PHP_EOL;'
            【解决方案8】:

            J.F. Sebastian 的解决方案在 Ubuntu 8.04 中对我不起作用。
            这是一个修改后的 Perl 版本,可以与旧的 1.X JSON 库一起使用:

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

            【讨论】:

              【解决方案9】:

              TidyJSON

              它是 C#,所以也许你可以用 Mono 编译它,并在 *nix 上工作。但不能保证,抱歉。

              【讨论】:

                【解决方案10】:

                对于 Node.js,您还可以使用“util”模块。它使用语法高亮、智能缩进,从键中删除引号,并使输出尽可能漂亮。

                cat file.json | node -e "process.stdin.pipe(new require('stream').Writable({write: chunk =>  {console.log(require('util').inspect(JSON.parse(chunk), {depth: null, colors: true}))}}))"
                

                【讨论】:

                  【解决方案11】:

                  TL;DR:对于表演,请使用jj -p < my.json

                  基准测试

                  我在这里采用了一些解决方案,并用下一个虚拟脚本对它们进行了基准测试:

                  function bench {
                      time (
                        for i in {1..100}; do
                          echo '{ "foo": "lorem", "bar": "ipsum" }'  | $@ > /dev/null
                        done
                      )
                  }
                  

                  这是我的 Mac 上的结果(8 GB 2133 MHz LPDDR3,2.3 GHz Intel Core i5):

                  bench python -m json.tool
                  # 3.60s user 1.24s system 88% cpu 5.448 total
                  bench jq
                  # 2.79s user 0.29s system 89% cpu 3.453 total
                  bench bat -p -l json
                  # 5.77s user 0.99s system 95% cpu 7.080 total
                  bench jj -p
                  # 0.19s user 0.26s system 85% cpu 0.529 total
                  bench xidel -s - -e '$json' --printed-json-format=pretty                      
                  # 1.27s user 0.77s system 91% cpu 2.234 total
                  

                  感谢 @peak 和您的 answer 发现 jj!

                  【讨论】:

                    【解决方案12】:

                    ydump 工具是一个 JSON 漂亮的打印机:

                    $ ydump my_data.json
                    {
                      "foo": "lorem",
                      "bar": "ipsum"
                    }
                    

                    或者您可以通过管道输入 JSON:

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

                    这可能是除了使用jq 工具之外最短的解决方案。

                    此工具是OCamlyojson 库的一部分,并记录在here 中。

                    在 Debian 及其衍生版本中,软件包 libyojson-ocaml-dev 包含此工具。或者,可以通过OPAM 安装yojson

                    【讨论】:

                      【解决方案13】:
                      $ sudo apt-get install edit-json
                      $ prettify_json myfile.json
                      

                      【讨论】:

                        【解决方案14】:

                        如果您安装了 Node.js,您可以使用一行代码自行创建一个。漂亮地创建一个文件:

                        > vim 漂亮

                        #!/usr/bin/env node
                        
                        console.log(JSON.stringify(JSON.parse(process.argv[2]), null, 2));
                        

                        添加执行权限:

                        > chmod +x 漂亮

                        > ./pretty '{"foo": "lorem", "bar": "ipsum"}'

                        或者如果您的 JSON 在文件中:

                        #!/usr/bin/env node
                        
                        console.log(JSON.stringify(require("./" + process.argv[2]), null, 2));
                        

                        > ./漂亮的文件.json

                        【讨论】:

                        • process.stdin.resume();变量输入 = ''; process.stdin.on('data', (data) => { input += data; }); process.stdin.on('end', () => { console.log(JSON.stringify(JSON.parse(input), null, 2)); });
                        【解决方案15】:

                        这里是使用Groovy 脚本的方法。

                        创建一个 Groovy 脚本,比如“pretty-print”

                        #!/usr/bin/env groovy
                        
                        import groovy.json.JsonOutput
                        
                        System.in.withReader { println JsonOutput.prettyPrint(it.readLine()) }
                        

                        使脚本可执行:

                        chmod +x pretty-print
                        

                        现在从命令行,

                        echo '{"foo": "lorem", "bar": "ipsum"}' | ./pretty-print
                        

                        【讨论】:

                        • 尽管我很喜欢 Groovy,但由于 JVM 的开销,它不太适合像这样的小脚本。我的非正式测量显示 jq 快了大约 50 倍。
                        【解决方案16】:

                        我想出了这个解决方案:https://calbertts.medium.com/unix-pipelines-with-curl-requests-and-serverless-functions-e21117ae4c65

                        # this in your bash profile
                        jsonprettify() {
                          curl -Ss -X POST -H "Content-Type: text/plain" --data-binary @- https://jsonprettify.vercel.app/api/server?indent=$@
                        }
                        
                        echo '{"prop": true, "key": [1,2]}' | jsonprettify 4
                        # {
                        #     "prop": true,
                        #     "key": [
                        #         1,
                        #         2
                        #     ]
                        # }
                        

                        无需安装任何东西,如果你有互联网连接和cURL,你就可以使用这个功能。

                        您是否在无法安装任何东西的另一台主机中,这将是解决该问题的完美解决方案。

                        【讨论】:

                          【解决方案17】:

                          你只需要使用 jq 如果没有安装jq,则需要先安装jq。

                          sudo apt-get update
                          sudo apt-get install jq
                          

                          安装jq之后就只需要使用jq了

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

                          输出看起来像

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

                          【讨论】:

                          • brew install jq,如果您使用的是 Mac。
                          【解决方案18】:

                          我是json-liner 的作者。它是将 JSON 转换为 grep 友好格式的命令行工具。试一试。

                          $ echo '{"a": 1, "b": 2}' | json-liner
                          /%a 1
                          /%b 2
                          $ echo '["foo", "bar", "baz"]' | json-liner
                          /@0 foo
                          /@1 bar
                          /@2 baz
                          

                          【讨论】:

                            【解决方案19】:
                            gem install jsonpretty
                            echo '{"foo": "lorem", "bar": "ipsum"}' | jsonpretty
                            

                            这个方法也是"Detects HTTP response/headers, prints them untouched, and skips to the body (for use with `curl -i')"

                            【讨论】:

                              【解决方案20】:

                              https://github.com/aidanmelen/json_pretty_print

                              from __future__ import unicode_literals
                              from __future__ import absolute_import
                              from __future__ import print_function
                              from __future__ import division
                              
                              import json
                              import jsonschema
                              
                              def _validate(data):
                                  schema = {"$schema": "http://json-schema.org/draft-04/schema#"}
                                  try:
                                      jsonschema.validate(data, schema,
                                                          format_checker=jsonschema.FormatChecker())
                                  except jsonschema.exceptions.ValidationError as ve:
                                      sys.stderr.write("Whoops, the data you provided does not seem to be " \
                                      "valid JSON.\n{}".format(ve))
                              
                              def pprint(data, python_obj=False, **kwargs):
                                  _validate(data)
                                  kwargs["indent"] = kwargs.get("indent", 4)
                                  pretty_data = json.dumps(data, **kwargs)
                                  if python_obj:
                                      print(pretty_data)
                                  else:
                                     repls = (("u'",'"'),
                                              ("'",'"'),
                                              ("None",'null'),
                                              ("True",'true'),
                                              ("False",'false'))
                                  print(reduce(lambda a, kv: a.replace(*kv), repls, pretty_data))
                              

                              【讨论】:

                                【解决方案21】:

                                使用 JavaScript/Node.js:查看vkBeautify.js plugin,它为 JSON 和 XML 文本提供了漂亮的打印。

                                它是用纯 JavaScript 编写的,小于 1.5 KB(缩小)并且速度非常快。

                                【讨论】:

                                  【解决方案22】:

                                  这是一个 Groovy 单行代码:

                                  echo '{"foo": "lorem", "bar": "ipsum"}' | groovy -e 'import groovy.json.*; println JsonOutput.prettyPrint(System.in.text)'
                                  

                                  【讨论】:

                                    【解决方案23】:

                                    如果您不介意使用第三方工具,您可以简单地curl 转至jsonprettyprint.org。这适用于您无法在机器上安装软件包的情况。

                                    curl -XPOST https://jsonprettyprint.org/api -d '{"user" : 1}'
                                    

                                    【讨论】:

                                    • 要将标准输入传送到此命令,请执行以下操作:echo '{ "foo": "lorem", "bar": "ipsum" }' | curl -XPOST https://jsonprettyprint.org/api -d @-
                                    【解决方案24】:
                                    【解决方案25】:

                                    您可以使用Xidel

                                    Xidel 是一个命令行工具,用于从 HTML/XML 页面或 JSON-API 下载和提取数据,使用 CSS、XPath 3.0、XQuery 3.0、JSONiq 或模式模板。它还可以创建新的或转换后的 XML/HTML/JSON 文档。

                                    Xidel 默认漂亮打印:

                                    $ xidel -s - -e '$json' <<< '{"foo":"lorem","bar":"ipsum"}'
                                    {
                                      "foo": "lorem",
                                      "bar": "ipsum"
                                    }
                                    

                                    或:

                                    $ echo '{"foo":"lorem","bar":"ipsum"}' | xidel -s - -e .
                                    {
                                      "foo": "lorem",
                                      "bar": "ipsum"
                                    }
                                    

                                    【讨论】:

                                      【解决方案26】:

                                      我的 JSON 文件没有被这些方法解析。

                                      我的问题类似于帖子Is Google data source JSON not valid?

                                      The answer to that post 帮我找到了解决方案。

                                      没有字符串键的JSON被认为是无效的。

                                      {id:'name',label:'Name',type:'string'}
                                      

                                      必须是:

                                      {"id": "name", "label": "Name", "type": "string"}
                                      

                                      此链接对一些不同的 JSON 解析器进行了很好的全面比较:http://deron.meranda.us/python/comparing_json_modules/basic

                                      这让我找到了http://deron.meranda.us/python/demjson/。我认为这个解析器比其他解析器更容错。

                                      【讨论】:

                                      • JSON 不允许单引号作为分隔符,一个理智的 JSON 解析器应该拒绝这样的输入。
                                      • 最后两个链接似乎已损坏(“deron.meranda.us 的服务器响应时间过长”)。
                                      【解决方案27】:

                                      如果您愿意,也可以使用在线工具。

                                      我发现http://jsonprettyprint.net 是最简单和最容易的。

                                      【讨论】:

                                        【解决方案28】:

                                        我知道原帖要求提供 shell 脚本,但有很多有用且不相关的答案可能对原作者没有帮助。 添加无关紧要:)

                                        顺便说一句,我无法使用任何命令行工具。

                                        如果有人想要简单的 JSON JavaScript 代码,他们可以这样做:

                                        JSON.stringfy(JSON.parse(str), null, 4)
                                        

                                        http://www.geospaces.org/geoweb/Wiki.jsp?page=JSON%20Utilities%20Demos

                                        这里的 JavaScript 代码不仅可以修饰 JSON,还可以按属性或按属性和级别对其进行排序。

                                        如果输入是

                                        { "c": 1, "a": {"b1": 2, "a1":1 }, "b": 1},
                                        

                                        它要么打印(将所有对象组合在一起):

                                        {
                                             "b": 1,
                                             "c": 1,
                                             "a": {
                                                  "a1": 1,
                                                  "b1": 2
                                             }
                                        }
                                        

                                        OR(只是按键命令):

                                        {
                                         "a": {
                                              "a1": 1,
                                              "b1": 2
                                         },
                                         "b": 1,
                                         "c": 1
                                        }
                                        

                                        【讨论】:

                                          猜你喜欢
                                          • 1970-01-01
                                          • 2012-10-11
                                          • 1970-01-01
                                          • 2012-10-08
                                          • 1970-01-01
                                          • 2013-10-03
                                          • 2011-08-05
                                          相关资源
                                          最近更新 更多