如何用单条yq脚本兼容单/多文档文件提取端口数据
兼容单/多文档的yq脚本解决方案
针对你的需求,这里提供一个基于mikefarah's yq 4.40.5的通用脚本,既能处理多文档Helm Service文件,也能兼容单文档场景,核心是通过递归筛选所有kind: Service节点来规避单/多文档的结构差异:
核心命令(输出到新文件)
yq eval-all ' # 提取所有Service文档中的port和nodePort,映射为kind需要的字段格式 (.. | select(kind == "Service") | .spec.ports[] | {containerPort: .port, hostPort: .nodePort}) as $newMappings # 加载目标配置文件,合并端口映射 | load("kind-config.yaml") | .extraPortMappings += $newMappings ' service-files.yaml > updated-kind-config.yaml
直接覆盖原kind-config.yaml的版本
如果不需要保留原配置文件的备份,可使用-i参数直接修改:
yq eval-all -i ' (.. | select(kind == "Service") | .spec.ports[] | {containerPort: .port, hostPort: .nodePort}) as $newMappings | load("kind-config.yaml") | .extraPortMappings += $newMappings ' service-files.yaml
关键逻辑说明
eval-all:强制yq处理输入中的所有文档,无论输入是单个还是多个Service文件.. | select(kind == "Service"):递归遍历所有节点,筛选出所有kind为Service的条目,自动适配单文档(单个Service节点)和多文档(多个Service节点数组)的结构.spec.ports[] | {containerPort: .port, hostPort: .nodePort}:遍历每个Service的端口列表,将Helm Service的port映射为kind配置的containerPort,nodePort映射为hostPort(可根据你的实际字段需求调整键名).extraPortMappings += $newMappings:将提取到的端口映射追加到目标数组中,如果extraPortMappings数组不存在,yq会自动创建
可选:过滤无nodePort的条目
如果ClusterIP类型的Service没有nodePort字段,你可以添加过滤条件排除这类条目:
yq eval-all -i ' (.. | select(kind == "Service") | .spec.ports[] | select(.nodePort != null) | {containerPort: .port, hostPort: .nodePort}) as $newMappings | load("kind-config.yaml") | .extraPortMappings += $newMappings ' service-files.yaml
内容的提问来源于stack exchange,提问作者Arikael
相关产品推荐
相关产品推荐

