Python:临时格式化 JSON,`python -m json.tool` 不用额外装包

59 次浏览6 条回复

调接口或者看日志时,偶尔会拿到一坨压成一行的 JSON。只是想临时看清楚结构的话,Python 自带的 json.tool 就够用了。

环境:Python 3.8+。可以直接在终端试:

printf '{"name":"dev","items":[1,2,3]}' | python -m json.tool

输出大概是:

{
    "name": "dev",
    "items": [
        1,
        2,
        3
    ]
}

如果 JSON 不合法,它也会直接报错,适合顺手验一下格式:

printf '{bad json}' | python -m json.tool

这个不适合替代正式的接口校验,只是本地排查时挺省事。尤其是服务器上不想临时装 jq 的时候,可以先拿它顶一下。

这个确实适合救急。还有个小用法:如果想压回一行,也可以加 --compact

printf '{"name":"dev","items":[1,2,3]}' | python -m json.tool --compact

在日志里要复制一段给别人时挺省事。不过参数好像是 Python 3.9+ 才有,老环境还是先看下 python -m json.tool -h 比较稳。

还可以顺手加 --sort-keys,看那种字段顺序乱七八糟的配置会舒服一点:

printf '{"b":2,"a":1}' | python -m json.tool --sort-keys

不过它会改变展示顺序,排查接口返回时还好;如果是在对比原始响应,还是别忘了这一点。

这个命令还可以直接接文件名,不一定非要管道。比如临时把一份压缩过的 JSON 展开到新文件:

python -m json.tool input.json pretty.json

它不会原地改 input.json,这一点反而安全点。想覆盖原文件的话我会先输出到临时文件,看一眼没问题再挪过去,避免手滑把坏内容写回去。

补一个小细节:如果 JSON 里有中文,默认输出可能会转成 \uXXXX。想保留中文可读一点,可以加 --no-ensure-ascii

printf '{"msg":"开发"}' | python -m json.tool --no-ensure-ascii

这个参数也是新一点的 Python 才有,服务器环境比较老的话先 -h 看一下。

如果日志是一行一个 JSON 的那种,也可以看看 --json-lines

printf '{"a":1}\n{"b":2}\n' | python -m json.tool --json-lines

它会按行分别解析,适合临时看 ndjson。普通 JSON 数组就不用这个参数了,不然反而容易误判。

缩进也能稍微调一下,默认 4 空格有时看日志会占太宽。比如想紧一点:

printf '{"name":"dev","items":[1,2,3]}' | python -m json.tool --indent 2

如果只是终端里扫一眼,2 空格会舒服点。老 Python 版本参数不全的话,还是先 python -m json.tool -h 看下。