unix 如何在shell脚本中缩小JSON?

00jrzges  于 2022-11-04  发布在  Unix
关注(0)|答案(5)|浏览(298)

我一直在寻找一种方法来丑化一些JSON,而在我的bash控制台。这有助于使用它在另一个命令(例如,传递json inline到httpie
赠送:

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

我想获得:

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

**注意:**这个问题是有意从it's pretty-print counterpart得到很大的启发。但是,在谷歌上搜索 bash minify json 没有给予一个合适的结果,因此这个问题是针对minify/uglify的。

qxgroojn

qxgroojn1#

您可以使用jq-c(精简)选项。
jq -c . < input.json

a7qyws3x

a7qyws3x2#

TL;DR

不安装

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

非常快(使用jj

jj -u < my.json

性能指标评测

下面是使用hyperfine的脚本:


# !/usr/bin/env bash

tmp=$(mktemp json.XXX)
tmp_md=$(mktemp md.XXX)

trap "rm $tmp $tmp_md" EXIT

cat <<JSON > $tmp
{
    "foo": "lorem",
    "bar": "ipsum"
}
JSON
hyperfine \
    --export-markdown $tmp_md \
    --warmup 100 \
    "jj -u < $tmp" \
    "yq eval -j -I=0 < $tmp" \
    "xidel -s - -e '\$json' --printed-json-format=compact < $tmp" \
    "jq --compact-output < $tmp" \
    "python3 -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)' < $tmp" \
    "ruby -r json -e 'j JSON.parse \$stdin.read' < $tmp"

pbcopy < $tmp_md

结果在我的mac - MacBook Air(M1,2020),8 GB:
| 指令|平均值[ms]|最小值[ms]|最大值[ms]|相对|
| - -|- -|- -|- -|- -|
| jj -u < json.p72个|1.3 ± 0.2| 0.9分|二点七|一点整|
| yq eval -j -I=0 < json.p72| 4.4 ± 0.4| 3.8分|七点八分|3.37 ± 0.65分|
| xidel -s - -e '$json' --printed-json-format=compact < json.p72| 5.5 ± 0.3| 5.0版本|六点五|4.19 ± 0.77分|
| python3 -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)' < json.p72| 14.0 ± 0.4|十三点四|15.0个|10.71 ± 1.89之间|
| jq --compact-output < json.p72| 14.4 ± 2.0分|13.2节|三十三点六|11.02 ± 2.45分|
| ruby -r json -e 'j JSON.parse $stdin.read' < json.p72| 47.3 ± 0.6|四十六点一|四十八点五|36.10 ± 6.32分|
大型JSON文件(14 k行)的结果:

http https://france-geojson.gregoiredavid.fr/repo/regions.geojson | jj -p > $tmp

| 指令|平均值[ms]|最小值[ms]|最大值[ms]|相对|
| - -|- -|- -|- -|- -|
| jj -u < json.wFY| 3.4 ± 0.7|二点七|12.2节|一点整|
| jq --compact-output < json.wFY| 35.1 ± 0.4|三十四点五|36.1分|10.24 ± 2.23分|
| python3 -c 'import json, sys;json.dump(json.load(sys.stdin), sys.stdout)' < json.wFY| 47.4 ± 0.5|四十六点三|四十八点七|13.82 ± 3.01分|
| xidel -s - -e '$json' --printed-json-format=compact < json.wFY个|55.5 ± 1.2|五十四点七|六十三点五|16.17 ± 3.53分|
| ruby -r json -e 'j JSON.parse $stdin.read' < json.wFY个|94.9 ± 0.7|九十三点八|九十六点八|27.65 ± 6.02分|
| yq eval -j -I=0 < json.wFY| 3087.0 ± 26.6分|小行星3049.3|小行星3126.8| 899.63 ± 195.81之间|
here is the pretty print对应的基准测试

c8ib6hqw

c8ib6hqw3#

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

bpzcxfmw

bpzcxfmw4#

使用xidel时:

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
vngu2lb8

vngu2lb85#

jq-缩小

下面是一个bash脚本,它将写回缩小的文件
可与bash v3.2+和jq v1.6+一起使用


# !/usr/bin/env bash

set -eu
path=
options=()

# change -c to -r to get pretty-print

set -- "$@" -c .
for arg; do
  if [ -f "$arg" ]; then
    if [ -n "$path" ]; then
      echo "Cannot specify multiple paths to jq-minify" >&2
      exit 1
    fi
    path="$arg"
  else
    options+=("$arg")
  fi
done
tmp=$(mktemp)
jq "${options[@]}" "$path" >"$tmp"
cat "$tmp" >"$path"

相关问题