【问题标题】:How can I minify JSON in a shell script?如何在 shell 脚本中缩小 JSON?
【发布时间】:2020-07-22 07:12:54
【问题描述】:

我一直在寻找一种在我的 bash 控制台中丑化一些 JSON 的方法。这有助于以后在另一个命令中使用它(例如,将 json 内联传递给 httpie

给予:

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

我要获取:

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

注意:这个问题的灵感来自it's pretty-print counterpart。然而,谷歌搜索 bash minify json 并没有给我一个正确的结果,因此这个问题是针对 minify/uglify 的。

【问题讨论】:

    标签: json unix command-line minify


    【解决方案1】:

    您可以使用jq -c(紧凑)选项。

    jq -c . < input.json

    【讨论】:

      【解决方案2】:

      TL;DR:使用jj -u < my.json 似乎是最有效的,使用jj 工具。

      但是,如果您已经安装了 python 并且不希望使用新的第三方工具来完成此类任务,那么使用 python 单线器是一种非常有效的方法:

      python -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)'  < my.json
      

      性能基准

      这是脚本,使用 ruby​​ 的 benchmark-ips:

      #!/usr/bin/env ruby
      # frozen_string_literal: true
      
      require "benchmark/ips"
      require "tempfile"
      
      commands= <<~SH.split("\n")
          python3 -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)'
          jq --compact-output
          xidel -s - -e '$json' --printed-json-format=compact
          jj -u
          yq eval -j -I=0
      SH
      
      def label(cmd)
          "%s (%s)" % [
              name = cmd.split.first,
              `#{name} --version 2>&1`[/\d+(\.\d+)*/]
          ]
      end
      
      file = Tempfile.new('foo')
      file.write <<~JSON
          {
              "foo": "lorem",
              "bar": "ipsum"
          }
      JSON
      file.close
      at_exit { file.unlink }
      
      Benchmark.ips do |x|
          commands.each do |cmd|
              x.report(label(cmd)) do
                  system(cmd, in: file.path, out: File::NULL) or raise label(cmd) + " failed"
              end
          end
          x.compare!
      end
      

      我的 Mac 上的结果(16 GB 2133 MHz LPDDR3,1.4 GHz 四核 Intel Core i5):

      Warming up --------------------------------------
           python3 (3.9.6)     2.000  i/100ms
                  jq (1.6)     3.000  i/100ms
             xidel (0.9.8)     4.000  i/100ms
                jj (1.2.3)    19.000  i/100ms
               yq (4.11.2)    10.000  i/100ms
      Calculating -------------------------------------
           python3 (3.9.6)     23.024  (± 0.0%) i/s -    116.000  in   5.040842s
                  jq (1.6)     34.140  (± 2.9%) i/s -    171.000  in   5.011323s
             xidel (0.9.8)     37.127  (±13.5%) i/s -    184.000  in   5.084564s
                jj (1.2.3)    170.997  (±13.5%) i/s -    836.000  in   5.014322s
               yq (4.11.2)     83.604  (±20.3%) i/s -    400.000  in   5.041262s
      
      Comparison:
                jj (1.2.3):      171.0 i/s
               yq (4.11.2):       83.6 i/s - 2.05x  (± 0.00) slower
             xidel (0.9.8):       37.1 i/s - 4.61x  (± 0.00) slower
                  jq (1.6):       34.1 i/s - 5.01x  (± 0.00) slower
           python3 (3.9.6):       23.0 i/s - 7.43x  (± 0.00) slower
      

      注意:Here is the pretty print benchmarkjj 也是最好的!

      【讨论】:

      • uglify-js 怎么样?
      • 如果你在谈论这个:lisperator.net/uglifyjs,它是一个 javascript uglifier,而不是 JSON。并且 node 在计算机上的使用频率低于 python。因此我不确定它是否是一个好的候选人:/
      • python 行示例:python -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)' &lt; myfile.json
      • 啊,很好。感谢您测试xidel
      • @UlysseBN 您能否包含/更新xidel 的最新development build 的结果?很多改进。也许您还可以在您的pretty print post 中包含xidel
      【解决方案3】:

      yq 为我工作,通过使用输入文件(包含美化的 JSON)
      yq eval -j -I=0 uglify-test.txt
      文档链接:https://mikefarah.gitbook.io/yq/usage/convert

      【讨论】:

      • 我已将其添加到基准测试中!它似乎比 jq 快得惊人!
      【解决方案4】:

      :

      xidel -s input.json -e '$json' --printed-json-format=compact
      #or
      xidel -s input.json -e 'serialize-json($json)'
      {"foo": "lorem", "bar": "ipsum"}
      

      有趣的“基准”,Ulysse BN。
      我无法测试jj,但在我的旧 CPU 上,这些是我的结果:

      var='{
          "foo": "lorem",
          "bar": "ipsum"
      }'
      
      time (for i in {1..100}; do python -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)' <<< "$var" >& /dev/null; done)
      
      real    0m10.813s
      user    0m7.532s
      sys     0m5.798s
      
      time (for i in {1..100}; do jq --compact-output <<< "$var" >& /dev/null; done)
      
      real    0m10.500s
      user    0m1.835s
      sys     0m0.769s
      
      time (for i in {1..100}; do xidel -se '$json' --printed-json-format=compact <<< "$var" >& /dev/null; done)
      
      real    0m2.250s
      user    0m1.692s
      sys     0m0.889s
      

      【讨论】:

      • 非常有趣的解决方案!我已将其添加到我的基准测试中,以使答案更易于阅读:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      相关资源
      最近更新 更多