yq 的 documentIndex 操作符:多文档 YAML 的按文档定位、筛选与溯源实战指南

发布时间:2026/9/14 8:48:50

yq 的 documentIndex 操作符:多文档 YAML 的按文档定位、筛选与溯源实战指南 yq 的 documentIndex 操作符多文档 YAML 的按文档定位、筛选与溯源实战指南【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq导读documentIndex别名di是 yq 中用于读取节点所属文档索引的核心操作符当输入文件包含多个用---分隔的 YAML 文档时它返回每个匹配节点所在文档的序号从 0 开始计数既可以直接输出索引值也可以与select组合按文档号精确过滤还能在构造结果时把匹配内容 文档号一并打包输出。读完本文你将掌握如何用documentIndex/di在多文档 YAML 中定位数据来源、按文档切片筛选以及这一功能在 yq 内部的实现原理源码位于 pkg/yqlib/operator_document_index.go。一、操作符速览documentIndex 与 didocumentIndex是一个零参数操作符NumArgs: 0在 yq 的表达式语法中写作documentIndex同时支持两个简写形式document_index与di。该别名关系由词法分析器统一注册见 pkg/yqlib/lexer_participle.go{DocumentIndex, documentIndex|document_?index|di, opToken(getDocumentIndexOpType), 0},即三种写法documentIndex、document_index、di在词法层面指向同一个操作类型getDocumentIndexOpType该类型在 pkg/yqlib/operation.go 中注册为var getDocumentIndexOpType operationType{Type: GET_DOCUMENT_INDEX, NumArgs: 0, Precedence: 50, Handler: getDocumentIndexOperator}其行为语义在 pkg/yqlib/doc/operators/document-index.md 中有明确定义返回输入流中每个匹配节点所属文档的索引。索引从 0 开始第一个文档为 0第二个为 1以此类推。二、检索文档索引确认每个节点来自哪个文档最直接的用法是把documentIndex接在任意路径表达式之后为每个匹配节点输出其文档号。假定文件sample.yml内容为两个文档a: cat --- a: frog执行yq .a | document_index sample.yml输出0 --- 1逐行解读.遍历到两个文档中各自的a节点管道|将每个节点依次送入document_index操作符对每个匹配节点分别返回其所在文档的索引因此结果与输入文档一一对应——第一个文档的a: cat来自文档 0第二个文档的a: frog来自文档 1输出时也以---分隔为两个独立文档。这一行为在 pkg/yqlib/operator_document_index_test.go 的测试场景中得到严格验证其期望结果逐字记录了 D0 与 D1 两个文档各自输出索引 0 和 1。三、使用简写 di同样的功能更短的表达式当表达式较长时可以使用di简写。对同一份sample.ymlyq .a | di sample.yml输出与完整写法完全一致0 --- 1由于di与documentIndex在词法层指向同一个操作类型见上文 lexer_participle.go二者没有任何行为差异可放心混用。同类场景下仓库的多文档示例文件 examples/multiple_docs.yaml 包含 3 个文档可以拿来实测yq .commonKey | di examples/multiple_docs.yaml会依次输出0、1、2对应三个文档中的commonKey节点。四、按文档索引过滤select 组合技documentIndex最常见的实战用途是作为select的过滤条件只保留指定文档中的节点。例如只取第二个文档yq select(document_index 1) sample.yml输出a: frog注意此处select作用于整个文档的根节点因此条件成立时输出的是整个文档文档 1 的全部内容a: frog而不是某个子节点。若想同时约束字段与文档可写成select(.a frog and document_index 1)这类复合条件。同样的过滤也可以用简写完成yq select(di 1) sample.yml输出a: frog测试用例 pkg/yqlib/operator_document_index_test.go 验证了select(document_index 1)与select(di 1)的期望结果均为D1, P[], (!!map)::a: frog——即只保留文档 1 的整份映射。这一模式非常适合从多文档配置中只取某一环境/某一段的场景。五、打印文档索引与匹配内容构建带来源标记的输出有时我们希望输出结果既包含匹配到的值、又标注它来自哪个文档。此时可以利用 yq 的对象构造语法{key: value}把document_index作为值写入结果对象的字段yq .a | ({match: ., doc: document_index}) sample.yml输出match: cat doc: 0 --- match: frog doc: 1拆解这个表达式.a选出两个文档中的a节点并逐个送入管道({match: ., doc: document_index})对每个节点构造一个映射——match字段存放原始节点值.doc字段存放该节点所在文档的索引。于是输出中内容与来源成对出现非常适合生成审计报告或调试多文档处理流水线。该场景同样有对应的测试断言见 pkg/yqlib/operator_document_index_test.go。六、源码原理文档索引是如何产生与读取的6.1 操作符实现逐节点读取并构造整数标量documentIndex的核心实现位于 pkg/yqlib/operator_document_index.gofunc getDocumentIndexOperator(_ *dataTreeNavigator, context Context, _ *ExpressionNode) (Context, error) { var results list.New() for el : context.MatchingNodes.Front(); el ! nil; el el.Next() { candidate : el.Value.(*CandidateNode) scalar : candidate.CreateReplacement(ScalarNode, !!int, fmt.Sprintf(%v, candidate.GetDocument())) results.PushBack(scalar) } return context.ChildContext(results), nil }处理逻辑非常直白遍历上下文中的所有匹配节点context.MatchingNodes对每个候选节点candidate调用GetDocument()取得其文档索引再用CreateReplacement生成一个类型为!!int的整数标量节点作为输出。这也是为什么上文所有示例的输出都是不带引号的整数值——它们在内部被构造为!!int类型而非字符串。6.2 文档号的传递子节点向上委托给父节点节点上的文档号并非每个节点都冗余存储而是采用向上委托策略。CandidateNode.GetDocument()的实现见 pkg/yqlib/candidate_node.gofunc (n *CandidateNode) GetDocument() uint { // defer to parent if n.Parent ! nil { return n.Parent.GetDocument() } return n.document }即只要节点存在父节点就递归向上查找直到根节点返回真正存储的document字段。这保证了.a之类的子节点查询也能正确报告它所属的文档——子节点无需单独维护文档号天然继承根节点的归属。6.3 文档索引从哪来解码器在解析时分配文档索引由各解码器在解析输入时按顺序分配。以 YAML 为例pkg/yqlib/decoder_yaml.go 声明了解码器结构中的documentIndex uint字段并在解析每个文档的根节点时写入 pkg/yqlib/decoder_yaml.gocandidateNode : CandidateNode{document: dec.documentIndex}随后在下一个文档开始时递增 pkg/yqlib/decoder_yaml.go 处的计数器。同样的机制也出现在 HCL 解码器中pkg/yqlib/decoder_hcl.go 的documentIndex字段与 pkg/yqlib/decoder_hcl.go 的递增逻辑。因此文档索引从 0 开始、按文档出现的先后顺序递增这一结论可以从解码器源码中得到直接确认。七、实战延伸多文档场景下的组合用法documentIndex的价值在于让多文档输入可寻址。yq 官方使用文档 pkg/yqlib/doc/usage/convert.md 也明确指出多文档输出中的文档由documentIndex/di操作符进行索引。以下是一些可立即落地的组合用法定位第二个文档yq select(di 1) sample.yml输出整份文档 1逐文档加工yq .a | . ! | select(di 0) sample.yml先修改再按文档过滤带来源的输出如第五节所示把document_index打包进对象字段便于下游程序区分数据出处配合多文档样例验证用 examples/multiple_docs.yaml3 个文档实测yq select(di 2) | .commonKey examples/multiple_docs.yaml会得到第三个文档的commonKey值。所有上述示例均可直接复制运行若要对照期望结果做自动化验证仓库中的 pkg/yqlib/operator_document_index_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),仅供参考
延伸阅读

更多相关文章

2026/9/14 8:48:50

办公智能体套件核心能力拆解与多智能体协作落地实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 8:48:50

解决uniapp微信小程序41002错误:AppID缺失问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 9:49:19

Vue组件开发:直接操作DOM与数据驱动的对比与实践

1. Vue组件开发的两种范式之争 在Vue项目开发中,组件化开发已经成为标配。但很多开发者经常面临一个基础却关键的选择题:到底该用直接操作DOM的传统写法,还是采用数据驱动的响应式写法?这个问题看似简单,却直接影响着项…

2026/9/14 9:49:18

Python SMTP加密端口邮件发送实战指南

1. Python实现加密端口发送邮件的核心原理在现代互联网通信中,邮件传输的安全性至关重要。Python通过内置的smtplib库提供了完整的SMTP协议实现,支持多种加密方式确保邮件传输安全。SMTP(Simple Mail Transfer Protocol)是用于发送…

2026/9/14 9:49:18

大模型转型实战:LangChain与RAG技术解析

1. 2026年大模型转型全景图:为什么现在就要开始准备? 大模型技术正在以惊人的速度重塑整个IT行业。根据行业观察,到2026年,超过70%的企业级应用都将集成大模型能力。作为技术人员,我们正站在一个关键的转型节点上——要…

2026/9/14 9:44:18

5 分钟跑通 Keep:AIOps 告警聚合与降噪怎么做到的

5 分钟跑通 Keep:AIOps 告警聚合与降噪怎么做到的 【免费下载链接】keep The open-source AIOps and alert management platform 项目地址: https://gitcode.com/GitHub_Trending/kee/keep 凌晨三点,Prometheus、Datadog、CloudWatch 同时炸出两三…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/14 0:03:22

KCF目标跟踪算法与OTB工程实现:毕业设计实战解析

简介:这是一份基于KCF核相关滤波算法、融合尺度池与抗遮挡处理的目标检测跟踪MATLAB完整源码,主要面向计算机相关专业准备毕业设计、课程设计或期末大作业的学生,也适合需要项目实战练习的初学者。源码在OTB数据集上完成验证,能够…

2026/9/14 0:03:22

语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比

简介:面向语音情感识别入门与进阶开发者,这份基于Keras的项目源码完整实现了LSTM、CNN、SVM、MLP四种模型,兼容Python3.8与Keras/TensorFlow2环境。压缩包内含49个文件,大小约70.31MB,主体包括Python脚本、yaml/json配…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码