You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取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

脚本说明

  1. 定义通用函数deduplicate(key):接收字段名参数key,内部完成「数组转映射去重→转回数组」的逻辑,后出现的同名字段会覆盖先出现的。
  2. 复用函数处理目标字段:分别传入"clusters"和"contexts",完成两个字段的去重合并。
  3. 保留基准文件的其他字段:通过select(fi == 0)确保最终输出保留第一个输入文件(konfig)中的非目标字段(如apiVersion、current-context)。

内容的提问来源于stack exchange,提问作者Noel Yap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:54:36