)
yq tag 运算符实战读取与设置节点类型标签!!str、!!int、!!bool【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yqtag是 yq 中用于读取或设置节点类型标签YAML Tag如!!str、!!int、!!bool的核心运算符在数据清洗、类型校验与格式转换场景中高频使用。本文基于 tag 官方文档 与仓库源码完整讲解tag的读取、赋值、别名type及与select组合的类型批量转换技巧并深入到 operator_tag.go 剖析其底层实现帮助你准确判断和改写 YAML、JSON、XML、CSV、TOML、HCL 与 properties 数据中的节点类型。tag 是什么YAML 节点的类型标签在 YAML 数据模型中每个节点除了值本身还带有一个描述其类型的标签Tag。yq 解析文档时会把类型信息记录为标准的 YAML Tag!!map映射对象!!seq序列数组!!str字符串!!int整数!!float浮点数!!bool布尔值!!null空值在 candidate_node.go 的createScalarNode中可以看到标签的推导规则Go 的int系列对应!!int、float系列对应!!float、bool对应!!bool、string对应!!str、nil对应!!null。yq 的tag运算符正是围绕这个标签字段提供读取和写入两种能力。读取节点标签.. | tag给定一个sample.ymla: cat b: 5 c: 3.2 e: true f: []执行yq .. | tag sample.yml输出!!map !!str !!int !!float !!bool !!seq这里..是递归下降运算符遍历文档中所有节点tag则依次取出每个节点的类型标签。输出顺序与..的遍历顺序一致先根节点!!map再按文档顺序逐个输出子节点类型。tag的返回值本身是!!str类型的标量因此可以直接参与字符串比较见下文select示例。type是tag的别名yq 同时提供了type作为tag的完全等价别名yq .. | type sample.yml输出与上面完全相同!!map !!str !!int !!float !!bool !!seq这一别名的注册位于 lexer_participle.goassignableOp(tag|type, getTagOpType, assignTagOpType)。正则tag|type同时匹配两种写法且两者都被声明为可赋值运算符即既支持tag读取也支持tag ...写入。设置自定义标签.a tag !!xxxtag可以作为赋值目标给指定节点打上任意标签。给定a: str执行yq .a tag !!mikefarah sample.yml输出a: !!mikefarah str赋值后节点的值仍是str但标签被改写为!!mikefarah。这在序列化时会影响输出形式也常用于为节点附加自定义类型语义。从源码看assignTagOperator 先求值右侧表达式expressionNode.RHS得到标签字符串再遍历左侧匹配到的所有候选节点逐一执行candidate.Tag tag因此一次赋值可以作用于多个节点。实战找出所有整数并转为字符串tag与select组合可以按类型过滤节点并批量改写类型。给定a: cat b: 5 c: 3.2 e: true执行yq (.. | select(tag !!int)) tag !!str sample.yml输出a: cat b: 5 c: 3.2 e: true执行过程拆解如下..递归遍历全部节点select(tag !!int)过滤出标签为整数的节点——此处只有b值为5命中tag !!str将命中节点的标签改写为字符串输出时b被序列化为带引号的字符串5而c: 3.2!!float与e: true!!bool保持不变。这是处理配置文件里数字被误识别、需要强制转字符串这类问题的标准解法可复制到批量数据处理流水线中。源码级原理getTagOperator 与 assignTagOperatoryq 将tag拆分为两个独立操作类型定义在 operation.go 与 operation.gogetTagOpTypeGET_TAG0 个参数优先级 50处理器为getTagOperator负责读取标签assignTagOpTypeASSIGN_TAG2 个参数优先级 40处理器为assignTagOperator负责写入标签。读取侧的 getTagOperator 实现非常直观遍历当前上下文中所有匹配节点取出candidate.Tag将其包装成一个!!str类型的标量节点返回——这就是为什么tag的输出总是字符串可以直接参与比较。写入侧的 assignTagOperator 还支持tag | ...UpdateAssign为真的自引用更新写法即右侧表达式可以引用当前节点本身例如.[] tag | .会把每个子节点自身的字符串值当作新标签。测试验证与注意事项operator_tag_test.go 用场景化测试完整覆盖了本文所有示例Get tag、type is an alias for tag、Set custom tag、Find numbers and convert them to strings以及两个值得注意的细节key 的 tag 不是 keykey运算符返回的是键名字符串而非键节点因此.a | key | tag的输出路径是a标签为!!str自定义标签也可以来自字符串值.[] tag | .将{a: !!frog, b: !!customTag}改写为{a: !!frog !!frog, b: !!customTag !!customTag}说明tag赋值右侧可以是任意表达式。此外标签信息在解码与编码环节都会被保留和回写candidate_node_yaml.go 从 YAML 节点直接继承node.Tag而 candidate_node_json.go 则为 JSON 数据按值类型推导!!null/!!float/!!int/!!bool/!!str标签因此tag运算符同样适用于 JSON、CSV 等其它格式输入。若需在格式化输出中使用标签信息可参考tag与 style 运算符 的配合以及 printer_node_info.go 中对节点元信息的统一建模。小结tag读取节点类型标签输出为!!str标量type与tag完全等价二者都是可赋值运算符tag !!xxx可为任意节点设置自定义标签支持批量与|自引用写法(.. | select(tag !!int)) tag !!str是按类型批量转换的经典模式底层实现由GET_TAG优先级 50与ASSIGN_TAG优先级 40两个操作类型支撑源码位于 operator_tag.go词法注册见 lexer_participle.go。掌握tag你就掌握了在 yq 中控制节点类型的入口无论是类型诊断、类型清洗还是跨格式转换都能精准命中目标节点。【免费下载链接】yqyq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor项目地址: https://gitcode.com/GitHub_Trending/yq/yq创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考