如何提取yq脚本通用逻辑,实现DRY原则?
基于DRY原则重构yq脚本,提取通用代码块
我有一段用于合并去重KubeConfig文件中clusters和contexts的yq脚本,目前针对两个字段的处理逻辑完全重复,想提取通用代码块,让脚本符合DRY(Don't Repeat Yourself)原则。
原yq脚本
yq eval-all ' .clusters = ( ( (.clusters[] | {.name: .}) as $item ireduce ({}; . * $item) ) as $uniqueMap | ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value) ) | .contexts = ( ( (.contexts[] | {.name: .}) as $item ireduce ({}; . * $item) ) as $uniqueMap | ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value) ) | select(fi == 0)' konfig monfig
待提取的通用代码块
其中«KEY»代表可替换的目标字段名(如clusters/contexts):
.<<KEY>> = ( ( (.<<KEY>>[] | {.name: .}) as $item ireduce ({}; . * $item) ) as $uniqueMap | ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value) )
输入文件
konfig文件
# konfig apiVersion: apiVersion-keep clusters: - cluster: certificate-authority-data: cad-0 server: server-0 name: name-0 - cluster: certificate-authority-data: cad-1-discard server: server-1-discard name: name-1 - cluster: certificate-authority-data: cad-2 server: server-2 name: name-2 contexts: - context: cluster: cluster-0 user: user-0 name: name-0 - context: cluster: cluster-1-discard user: user-1-discard name: name-1 - context: cluster: cluster-2 user: user-2 name: name-2 current-context: name-keep
monfig文件
# monfig apiVersion: apiVersion-discard clusters: - cluster: certificate-authority-data: cad-1-keep server: server-1-keep name: name-1 contexts: - context: cluster: cluster-1-keep user: user-1-keep name: name-1 current-context: name-discard
预期输出
apiVersion: apiVersion-keep clusters: - cluster: certificate-authority-data: cad-0 server: server-0 name: name-0 - cluster: certificate-authority-data: cad-1-keep server: server-1-keep name: name-1 - cluster: certificate-authority-data: cad-2 server: server-2 name: name-2 contexts: - context: cluster: cluster-0 user: user-0 name: name-0 - context: cluster: cluster-1-keep user: user-1-keep name: name-1 - context: cluster: cluster-2 user: user-2 name: name-2 current-context: name-keep
重构后的DRY风格脚本
利用yq的def关键字定义通用去重函数,实现逻辑复用:
yq eval-all ' def deduplicate(key): .[key] = ( (.[key][] | {.name: .}) as $item ireduce ({}; . * $item) | to_entries | .[] | .value ); deduplicate("clusters") | deduplicate("contexts") | select(fi == 0) ' konfig monfig
脚本说明
- 定义通用函数
deduplicate(key):接收字段名参数key,内部完成「数组转映射去重→转回数组」的逻辑,后出现的同名字段会覆盖先出现的。 - 复用函数处理目标字段:分别传入
"clusters"和"contexts",完成两个字段的去重合并。 - 保留基准文件的其他字段:通过
select(fi == 0)确保最终输出保留第一个输入文件(konfig)中的非目标字段(如apiVersion、current-context)。
内容的提问来源于stack exchange,提问作者Noel Yap
相关产品推荐
相关产品推荐

