新闻详情

新闻详情

首页 / 资讯中心 / 详情

yq JSON 转换完全指南:解析、编码、NDJSON 多文档往返与源码级实现原理

发布时间:2026/9/14 15:33:59来源:尧图网络
yq JSON 转换完全指南:解析、编码、NDJSON 多文档往返与源码级实现原理
yq JSON 转换完全指南解析、编码、NDJSON 多文档往返与源码级实现原理【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq本文围绕 yq 仓库中的官方文档 pkg/yqlib/doc/usage/convert.md 展开系统讲解如何用 yq 在 JSON 与 YAML 之间进行解析、编码与往返转换覆盖 NDJSONJSON Lines多文档处理、按文档索引更新等全部官方示例并结合 pkg/yqlib 下的解码器、编码器与候选节点源码说明-pjson、-ojson、-I等参数背后的实现机制读完即可掌握 yq 处理 JSON 数据流的完整能力。为什么 JSON 转换是 yq 的基础能力yq 是一个可移植的命令行 YAML、JSON、XML、CSV、TOML、HCL 和 properties 处理器。JSON 转换在其中的特殊之处在于两点YAML 是单文档JSON 的超集。当输入只有一个 JSON 文档时你甚至不必显式指定 JSON 解析器直接让 yq 按 YAML 解析即可但为了输出符合 YAML 习惯的排版idiomatic YAML styling官方文档建议使用-P或--prettyPrint来美化结果见 cmd/root.go 中prettyPrint的注册。多文档 JSONNDJSON / JSON Lines超出了 YAML 的表达能力此时必须使用-pjson让 yq 用专门的 JSON 解码器流式地一次读取一个文档。从源码结构看yq 将每种格式抽象为 pkg/yqlib/format.go 中的Format结构体JSON 对应JSONFormat正式名为json、别名为jvar JSONFormat Format{json, []string{j}, func() Encoder { return NewJSONEncoder(ConfiguredJSONPreferences) }, func() Decoder { return NewJSONDecoder() }, }-p--input-format和-o--output-format参数默认值都是autoyq 会依据文件扩展名自动探测格式——pkg/yqlib/format.go 中的FormatStringFromFilename会取扩展名去匹配Formats列表匹配不到则回退为yaml。因此yq sample.json实际上已等价于yq -pjson sample.json显式写-pjson的价值主要在于管道输入stdin或扩展名不标准时的确定性。JSON 编解码的参数配置集中在 pkg/yqlib/json.gotype JsonPreferences struct { Indent int ColorsEnabled bool UnwrapScalar bool } func NewDefaultJsonPreferences() JsonPreferences { return JsonPreferences{ Indent: 2, // 默认缩进 2 空格 ColorsEnabled: true, UnwrapScalar: true, } }命令行侧缩进由 cmd/root.go 的-I/--indent默认 2控制它会写入ConfiguredJSONPreferences.Indent。下面所有示例的命令与输出均继承自官方文档可直接在 examples/sample.json 之类的样本文件上验证。解析 JSON单文档场景简单 JSON由于 JSON 是 YAML 的子集把 JSON“解析”出来其实只需把输出排版好。给定sample.json{cat: meow}执行yq -pjson sample.json输出cat: meow复杂 JSON嵌套对象与数组同样会被展开为 YAML 结构。给定{a:Easy! as one two three,b:{c:2,d:[3,4]}}执行yq -pjson sample.json输出a: Easy! as one two three b: c: 2 d: - 3 - 4这两类场景在测试中的对应关系可以在 pkg/yqlib/json_test.go 的jsonScenarios里找到scenarioType: decode-ndjson表示“JSON 解码 YAML 编码”的组合且测试用真实运行结果断言输出保证文档示例可复现。编码为 JSON从 YAML 输出 JSON基础编码给定sample.ymlcat: meow执行yq -ojson . sample.yml输出{ cat: meow }注意默认缩进为 2 空格来自JsonPreferences.Indent的默认值-I参数即直接覆盖该值。单行输出indent 0给定cat: meow # this is a comment, and it will be dropped.执行yq -ojson -I0 . sample.yml输出{cat:meow}-I0时NewJSONEncoder会构建空缩进串底层json.Encoder.SetIndent(, )输出紧凑单行 JSON这是与 NDJSON 场景配合的关键见 pkg/yqlib/encoder_json.go 中根据prefs.Indent逐字符拼接缩进串的逻辑。注释会被丢弃JSON 规范没有注释YAML 中的注释在编码为 JSON 时不会保留。给定cat: meow # this is a comment, and it will be dropped.执行yq -ojson . sample.yml输出{ cat: meow }锚点会被解引用JSON 不支持 YAML 锚点/别名yq 在编码时会将其解引用为实际值。给定cat: ref meow anotherCat: *ref执行yq -ojson . sample.yml输出{ cat: meow, anotherCat: meow }从源码结构看pkg/yqlib/encoder_json.go 中 JSON 编码器声明CanHandleAliases() bool返回false即 JSON 输出管线天然不携带别名节点遇到AliasNode时 pkg/yqlib/candidate_node_json.go 的MarshalJSON会直接编码o.Alias指向的目标节点从而完成解引用。多个结果每个匹配节点独立成文档当表达式匹配到多个节点时每个匹配节点都会被转换为一个独立的 JSON 文档。这种场景最适合搭配-I0每行一个 JSON 文档。给定things: [{stuff: cool}, {whatever: cat}]执行yq -ojson -I0 .things[] sample.yml输出{stuff:cool} {whatever:cat}这正是把任意数据源切片为 NDJSON 流例如喂给逐行消费jq或后端批处理接口的标准姿势。保留带末尾零的小数整数值的小数会保留小数点让下游消费者看到一个“带小数部分的 JSON 数字”与 Go 的encoding/json、Python 的json以及jq的行为一致。给定percentiles: [50.0, 95.0, 99.0, 99.9]执行yq -ojson -I0 . sample.yml输出{percentiles:[50.0,95.0,99.0,99.9]}这一行为的实现位于 pkg/yqlib/candidate_node_json.go 的jsonFloatLiteral函数对标记为!!float的标量优先原样保留其文本形式50.0保持50.0若原文不是合法 JSON 数字字面量则格式化后补.0遇到.inf/.nan等非有限浮点数则回退到常规编码路径。配套测试Encode json: ints stay ints、!!float tagged whole number gets .0、scientific notation float preserved等见 pkg/yqlib/json_test.go共同保证了“整数仍是整数、!!float 5变成5.0、科学计数法原样保留”的精确语义。NDJSON / JSON Lines 往返JSON Lines 往返给定sample.json{this: is a multidoc json file} {each: [line is a valid json document]} {a number: 4}执行yq -pjson -ojson -I0 sample.json输出{this:is a multidoc json file} {each:[line is a valid json document]} {a number:4}多行 JSON 多文档往返JSON Lines 规范约定“一行一个文档”但 yq 的 JSON 解析器还能处理单个文件中多个多行JSON 文档。给定{ this: is a multidoc json file } { it: [ has, consecutive, json documents ] } { a number: 4 }执行yq -pjson -ojson -I2 sample.json输出{ this: is a multidoc json file } { it: [ has, consecutive, json documents ] } { a number: 4 }多文档是如何实现的这是本文档最能体现源码价值的一点。查看 pkg/yqlib/decoder_json.gotype jsonDecoder struct { decoder json.Decoder } func (dec *jsonDecoder) Init(reader io.Reader) error { dec.decoder *json.NewDecoder(reader) return nil } func (dec *jsonDecoder) Decode() (*CandidateNode, error) { var dataBucket CandidateNode err : dec.decoder.Decode(dataBucket) if err ! nil { return nil, err } return dataBucket, nil }JSON 解码器持有一个流式json.Decoder来自github.com/goccy/go-jsonInit时绑定到输入 reader每调用一次Decode就从流中消费“恰好一个”顶层 JSON 值返回一个CandidateNode。yq 主循环反复调用Decode直到出错EOF于是每读到一个顶层 JSON 值就自然形成一个 yq 文档——无论是“一行一个”的 NDJSON还是“多行一个”的连续文档都只是流中先后出现的顶层值而已。这就是该解析器能同时支持两种布局的根本原因。而每个顶层值如何变成 yq 节点树见 pkg/yqlib/candidate_node_json.go 的UnmarshalJSON以{开头则构建MappingNode用dec.Token()逐个读 key/value保持键的原始顺序以[开头则构建SequenceNode每个元素挂一个整型索引键其余按标量处理。标量转换在setScalarFromJson中完成其中一个微妙细节是Go 的 JSON 解码器把整数也返回为float64源码会检测“伪装的整数”并修正为!!int标签candidate_node_json.go保证4不会被下游当作浮点数。测试Decode JSON Lines / NDJSON, maintain key orderjson_test.go专门验证了键序保持。多文档中定位更新di操作符文档可以用documentIndex缩写di操作符按下标定位。给定{this: is a multidoc json file} {each: [line is a valid json document]} {a number: 4}执行yq -pjson -ojson -I0 (select(di 1) | .each ) cool sample.json输出{this:is a multidoc json file} {each:[line is a valid json document,cool]} {a number:4}di 1选中第二个文档下标从 0 开始对其each数组追加cool其余文档原样透传。按内容查找并更新文档不依赖下标、用常规表达式按内容定位同样可行yq -pjson -ojson -I0 (select(has(each)) | .each ) cool sample.json输出同上{this:is a multidoc json file} {each:[line is a valid json document,cool]} {a number:4}has(each)筛出含有该键的文档再对其执行数组追加。这两条命令是“流式 ETL”的典型形态从 stdin 读入 NDJSON 事件流按条件改写特定事件后写回 stdout。解码 NDJSON 为 YAML给定同样的三行 NDJSON{this: is a multidoc json file} {each: [line is a valid json document]} {a number: 4}执行yq -pjson sample.json输出this: is a multidoc json file --- each: - line is a valid json document --- a number: 4每个 JSON 文档被转成一个 YAML 文档文档间以---分隔。注意此例中-o未指定默认按输入格式/自动探测输出为 YAML若你希望“JSON 进、YAML 出”后继续用 yq 表达式处理只需在文件位置前加上表达式即可例如yq -pjson .this sample.json。参数速查与实现对照参数作用源码依据-pjson--input-format指定输入按 JSON 流式解析支持 NDJSON 与连续多文档decoder_json.go 流式Decode-ojson--output-format每个结果节点编码为一个 JSON 文档encoder_json.go 的Encode-I0/-I2--indentJSON 缩进0输出单行紧凑 JSON适合 NDJSONencoder_json.go 按Indent拼接缩进串-P--prettyPrint美化输出等价于... style cmd/root.go-j/--tojson已废弃等价于-ojson单行输出需配合-I0cmd/root.go 中的MarkDeprecateddi/documentIndex按文档下标定位多文档中的特定文档表达式层操作符见 pkg/yqlib/doc/operators/document-index.md几个值得注意的实现细节不转义 HTML 字符encoder_json.go 中显式调用encoder.SetEscapeHTML(false)因此、、在输出中保持原样不会被转成\u0026之类的序列这对包含 URL 或 XML 片段的 JSON 尤为重要。标量解包-r/--unwrapScalarJsonPreferences.UnwrapScalar默认为true当表达式结果本身是标量且启用解包时encoder_json.go 会直接写出去掉引号的裸值加换行。文档中的往返测试场景特意将UnwrapScalar置为false以保证 NDJSON 文档原样输出见 json_test.go。文档生成机制官方文档 convert.md 并非手写维护而是由 pkg/yqlib/json_test.go 的TestJSONScenarios在测试时真实运行编码器/解码器、把结果写入doc/usage目录生成的标记skipDoc: true的场景只跑测试不出现在文档中。这意味着本文引用的每个命令与输出都经过自动化断言与当前仓库版本严格一致。小结单文档 JSON 可直接按 YAML 超集读取配合-P美化多文档/NDJSON 必须显式-pjson。YAML 编码为 JSON 用-ojson-I0得到单行 NDJSON注释被丢弃、锚点被解引用、50.0这类带小数点的浮点被精确保留。多文档更新用di下标或select(has(...))内容匹配配合-I0即可构建“NDJSON 进、NDJSON 出”的流式处理管道。所有行为的实现锚点流式解析在 pkg/yqlib/decoder_json.go节点树构建在 pkg/yqlib/candidate_node_json.go格式注册与自动探测在 pkg/yqlib/format.go默认参数在 pkg/yqlib/json.go回归与文档生成测试在 pkg/yqlib/json_test.go。【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

BGE 文本嵌入模型完全指南:5 分钟搭好检索 + RAG 完整流程 2026/9/14 19:07:31

BGE 文本嵌入模型完全指南:5 分钟搭好检索 + RAG 完整流程

BGE 文本嵌入模型完全指南:5 分钟搭好检索 RAG 完整流程 【免费下载链接】FlagEmbedding Retrieval and Retrieval-augmented LLMs 项目地址: https://gitcode.com/GitHub_Trending/fl/FlagEmbedding BGE 是智源研究院开源的通用文本嵌入模型(把…

阅读更多 →
创意项目管理:从无标题到高效命名的实践指南 2026/9/14 19:07:31

创意项目管理:从无标题到高效命名的实践指南

1. 项目概述作为一名从业多年的技术博主,我经常遇到一个困扰:当灵感突然来临时,却因为各种原因无法立即为项目想出一个完美的标题。这种情况在创意工作者中非常普遍——我们可能已经有了完整的项目构思和实施方案,却卡在了"起…

阅读更多 →
5分钟跑通JeecgBoot微服务:Nacos服务注册与配置中心实操指南 2026/9/14 19:07:31

5分钟跑通JeecgBoot微服务:Nacos服务注册与配置中心实操指南

5分钟跑通JeecgBoot微服务:Nacos服务注册与配置中心实操指南 【免费下载链接】jeecg-boot 【低代码v2.0,一句话即可生成整个系统】企业级AI低代码平台,一键生成前后端代码甚至整个系统。 AI Skills 一句话画流程、设计表单、生成报表、大屏。…

阅读更多 →
OpenClaw API 用量与成本管理:付费能力地图、密钥发现机制与用量可见性全景 2026/9/14 19:07:30

OpenClaw API 用量与成本管理:付费能力地图、密钥发现机制与用量可见性全景

OpenClaw API 用量与成本管理:付费能力地图、密钥发现机制与用量可见性全景 【免费下载链接】openclaw The AI that really does things. Any OS. Any Platform. The lobster way. 🦞 项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw …

阅读更多 →
ArduPilot 固件适配指南:Matek H7A3-SLIM 飞控硬件详解与 hwdef 配置剖析 2026/9/14 19:07:30

ArduPilot 固件适配指南:Matek H7A3-SLIM 飞控硬件详解与 hwdef 配置剖析

ArduPilot 固件适配指南:Matek H7A3-SLIM 飞控硬件详解与 hwdef 配置剖析 【免费下载链接】ardupilot ArduPlane, ArduCopter, ArduRover, ArduSub source 项目地址: https://gitcode.com/GitHub_Trending/ar/ardupilot 本文以 ArduPilot 仓库中 MatekH7A3 硬…

阅读更多 →
成考能提前毕业吗?政策边界与几种常见误解(2026 更新) 2026/9/14 19:04:30

成考能提前毕业吗?政策边界与几种常见误解(2026 更新)

直接答案:一般情况下不能。学制是规定的学习年限,不能通过缴费或申请提前毕业;能缩短的只有“入学前的准备期”。 成考没有提前毕业这一操作。学制是规定的学习年限,缴费和申请都改不了它。流传的两年拿证,多半是把学制…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞