如何在 shell 脚本中缩小 JSON?

Uly*_* BN 13 unix command-line json minify

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

给予:

{
    "foo": "lorem",
    "bar": "ipsum"
}
Run Code Online (Sandbox Code Playgroud)

我想获得:

{"foo":"lorem","bar":"ipsum"}
Run Code Online (Sandbox Code Playgroud)

注意:这个问题的灵感来自它的漂亮印刷版。然而,谷歌搜索bash minify json并没有给我一个正确的结果,因此这个问题是针对 minify/uglify 的。

Uly*_* BN 15

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

但是,如果您已经安装了 python 并且不想要一个新的第三方工具来完成这样的任务,python 单线是一种非常有效的方法:

python -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)'  < my.json
Run Code Online (Sandbox Code Playgroud)

性能基准

这是使用 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
Run Code Online (Sandbox Code Playgroud)

我的 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
Run Code Online (Sandbox Code Playgroud)

注意:这是漂亮的打印基准jj也是最好的!


gui*_*izo 14

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

jq -c . < input.json