Windows 批处理 - 漂亮打印 JSON 每个脚本

Windows Batch - Pretty Print JSON per Script

我在服务器上有多个 JSON 文件,它们只能 运行 批处理脚本或命令行工具。 JSON 文件的格式都不正确,这意味着行首没有制表符。

有没有办法,写一个批处理脚本或者运行一个命令行工具来格式化文件,让它们恢复正常?

你肯定需要一个外部工具。我正在使用 command-line JSON processor jq - 只需将身份过滤器 . 传递给它,它就会漂亮地打印出作为输入给出的 JSON。

更新:更正语法(从哪里来的?),抱歉@Delfic 和@Sonata。尽管我原来的答案中的空过滤器 "" 有效,但我像@Wolf 所说的那样更改了过滤器,因为它确实在 manual 中被称为“绝对最简单的过滤器”。

示例:

ECHO { "att1": 1, "att2": 2 } | jq .

输出:

{
  "att1": 1,
  "att2": 2
}

如果你想直接从shell处理JSON输入,你也可以使用空输入-n:

jq -n "{ "att1" : 1, "att2" : 2 }"

要处理文件,请执行:

jq . dirty.json

...或者,如果您愿意:

TYPE dirty.json | jq .

如果您安装了 python,则超级快速的方法是在命令提示符或 powershell 中键入以下内容:

type dirty.json | python -m json.tool > pretty.json

其中 dirty.json 被缩小或不可读 json 而 pretty.json 是漂亮的。您甚至可以通过传递参数将其放入批处理文件中 运行。它的处理速度非常快。

解释: type 正在将文件内容写入控制台,但它是通过管道传输的,因此它被发送到 python 的模块 json.tool,然后 '>' 将输出写入名为 'pretty.json' 的文件中。尝试不使用 > pretty.json 以查看控制台中的输出。

Windows' cmd 功能非常有限,对 JSON 的支持当然不是其中之一,所以我建议不要创建批处理脚本!不过,我强烈推荐命令行工具 。它默认美化。

标准输入:

ECHO {"a":1,"b":2,"c":3} | xidel -se "$json"
{
  "a": 1,
  "b": 2,
  "c": 3
}

(如果输入是JSON,xidel会解析并赋值给(内部)全局变量$json

File/url:

xidel -s "input.json" -e "$json"
#or
xidel -s "https://[...]" -e "$json"
#or
xidel -se "json-doc('file-or-url')"

写入文件:

xidel -s "input.json" -e "$json" > output.json
#or
xidel -s "input.json" -e "file:write('output.json',$json,{'method':'json','indent':true()})"
#or
xidel -se "file:write('output.json',json-doc('input.json'),{'method':'json','indent':true()})"

处理多个文件:

FOR %A IN (*.json) DO @xidel -s %A -e "$json" > %~nA_pretty.json

虽然这对目录中的许多 JSON 文件有效,但它也 非常 慢,因为 xidel 为每个 JSON 文件调用。
xidel 可以通过集成的 EXPath File Module.

更有效地做到这一点
xidel -se "file:list(.,false,'json')"

这 return 是当前目录中所有 JSON 文件的简单列表。
(相当于 DIR *.json /B FOR %A IN (*.json) DO @ECHO %A

xidel -se "file:list(.,false,'json') ! file:read-text(.)"
#or
xidel -se "for $x in file:list(.,false,'json') return file:read-text($x)"

两个命令 return 当前目录中每个 JSON 文件的内容。
(相当于 FOR %A IN (*.json) DO @TYPE %A

xidel -se "file:list(.,false,'json') ! json-doc(.)"
#or
xidel -se "for $x in file:list(.,false,'json') return json-doc($x)"

两个命令 return 当前目录中每个 JSON 文件的美化解析 JSON 内容。
(相当于 FOR %A IN (*.json) DO @xidel -s %A -e "$json",但 更快!)

xidel -se "file:list(.,false,'json') ! file:write(substring-before(.,'.json')||'_pretty.json',json-doc(.),{'method':'json','indent':true()})"
#or
xidel -se "for $x in file:list(.,false,'json') return file:write(substring-before($x,'.json')||'_pretty.json',json-doc($x),{'method':'json','indent':true()})"

这两个命令将当前目录中每个 JSON 文件的美化解析 JSON 内容写入一个新文件,文件名以“_pretty”结尾。

美化的最终命令(带有必要的转义字符):

xidel -se ^"^
  for $x in file:list(.,false,'json') return^
  file:write(^
    substring-before($x,'.json')^|^|'_pretty.json',^
    json-doc($x),^
    {'method':'json','indent':true()}^
  )^
"

请从推荐的 "Development"-branch 下载 xidel 二进制文件以使用这些查询(尤其是 json-doc())。
如果你坚持使用xidel 0.9.8,那么使用json(file:read-text($x))而不是json-doc($x)

本着 dnafication's 的精神 - 如果您有 perl,您可以:

TYPE dirt.json | perl -MJSON -0ne "print JSON->new->pretty->encode(decode_json $_)"

这适用于任何比 5.14(2011 年 5 月 14 日发布)更新的 perl,因为 JSON::PP 从那时起就是一个核心模块。请注意,这是一个纯 perl 实现,其性能不如例如JSON::XSRead this for details.