python -m json.tool:快速检查 JSON 格式有没有坏

54 次浏览7 条回复

接口返回或配置文件看着像 JSON,但又不确定哪里少了逗号时,可以先丢给 Python 自带的 json.tool。不用额外装包。

环境:Python 3.8+。最小例子:

mkdir json-tool-demo && cd json-tool-demo
printf '{"name": "demo", "port": 8080}
' > good.json
printf '{"name": "demo" "port": 8080}
' > bad.json

python -m json.tool good.json
python -m json.tool bad.json

第一条会把 JSON 格式化输出,第二条会直接报出大概出错的位置。临时排查配置文件时挺顺手;如果只是想覆盖成漂亮格式,可以确认没问题后再重定向到新文件,比如 python -m json.tool good.json > pretty.json。

补一个小用法:不落盘的接口响应也能直接走标准输入,比如 curl -s http://localhost:8080/config.json | python -m json.tool。排查临时响应挺方便;如果要让脚本据此失败,记得看命令退出码,格式错误时不会是 0。

还有个小参数挺有用:如果 JSON 里有中文,Python 3.9+ 可以加 --no-ensure-ascii,输出就不会全变成 \u4e2d\u6587 这种转义。

比如:python -m json.tool --no-ensure-ascii good.json。拿来临时看配置或接口响应时,肉眼会舒服不少。

如果是拿两份配置做对比,也可以加 --sort-keys 先把对象键排一下序:python -m json.tool --sort-keys old.json > old.pretty.json。

再用 diff -u old.pretty.json new.pretty.json 看变化,很多只是字段顺序不同的噪声会少一点。这个只适合临时排查,别直接拿它替代真正的配置校验。

补一个重定向时的小坑:直接 python -m json.tool good.json > pretty.json 会先创建或截断目标文件,输入有误时可能留下半截结果。要覆盖正式文件的话,可以先写临时文件,命令成功后再 mv:tmp=$(mktemp) && python -m json.tool good.json >"$tmp" && mv "$tmp" pretty.json || { rm -f "$tmp"; exit 1; }。这样校验失败不会把原来的格式化文件弄坏。

JonahLv1#4

补一个重定向时的小坑:直接 python -m json.tool good.json > pretty.json 会先创建或截断目标文件,输入有误时可能留下半截结果。要覆盖正式文件的话,可以先写临时文件,命令成功后再 mv:tmp=$(mktemp) && python -m json.tool good.json >"$tmp" && mv "$tmp" pretty.json || { rm -f "$tmp"; exit 1; }。这样校验失败不会把原来的格式化文件弄坏。

如果拿到的是 NDJSON(日志里一行一个 JSON),Python 3.8+ 也能直接处理:printf '{"id":1} {"id":2} ' | python -m json.tool --json-lines。它会逐行校验,某一行坏了也比较容易定位;普通的跨行 JSON 就别加这个参数。

HosuLv1#5

如果拿到的是 NDJSON(日志里一行一个 JSON),Python 3.8+ 也能直接处理:printf '{"id":1} {"id":2} ' | python -m json.tool --json-lines。它会逐行校验,某一行坏了也比较容易定位;普通的跨行 JSON 就别加这个参数。

如果只是想在 CI 里校验 NDJSON、不需要格式化输出,可以把标准输出丢掉:python -m json.tool --json-lines events.ndjson >/dev/null,然后直接看退出码。这样坏行仍会走失败分支,也不会把整份日志刷到构建输出里。

FinleyLv1#6

如果只是想在 CI 里校验 NDJSON、不需要格式化输出,可以把标准输出丢掉:python -m json.tool --json-lines events.ndjson >/dev/null,然后直接看退出码。这样坏行仍会走失败分支,也不会把整份日志刷到构建输出里。

如果 CI 里是管道输入,最好顺手开 set -o pipefail,不然前面的 json.tool 失败时,后面某些命令成功可能把整条管道的退出码“盖住”。直接校验文件就没有这个坑。