【问题标题】:Merging YAML arrays, ignoring other fields in the YAML合并 YAML 数组,忽略 YAML 中的其他字段
【发布时间】:2021-01-08 20:41:32
【问题描述】:

我正在寻找一种方法来合并来自两个独立 YAML 的数组(将一个附加到另一个)。但是,YAML 有一个用 {} 包裹的字段(不在数组中),可以用运行时值替换。即

# yaml a
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: {clusterRoleName}
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]

# yaml b
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: {clusterRoleName}
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "watch", "list"]

# desired
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: default
  name: {clusterRoleName}
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "watch", "list"]

为此,我使用的是 yq 版本 2.14。我试过yq merge -a=append a.yaml b.yaml,它可以根据需要处理规则数组,但将name: {clusterRoleName} 视为JSON 并输出:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: {ClusterRoleName: ''}
...

有没有办法只合并一个字段,或者忽略特定的键或值类型?如果有人能够建议另一种方法,我也不会为此使用 yq。

【问题讨论】:

  • 你能升级到最近的版本吗? v4 中有很多新功能
  • 升级可能是一种选择,尽管这种特定用途是大型项目的一部分,因此理想的解决方案是找到适用于现有版本的解决方案。如果在 v4 中有一个干净的方式,虽然会感兴趣 - 会检查一下谢谢:)

标签: yaml yq


【解决方案1】:

虽然使用专用的 yaml 解析器(例如 yq)是理想的选择,但使用 awk 可能是一种替代方案:

 awk 'NR==FNR && !/^[[:space:]]/ { tag=$1;next } tag=="rules:" && FNR==NR { map[idx++]=$0 } END { tag="" } NR!=FNR && !/^[[:space:]]/ { if (tag=="rules:") { for (i in map) { print map[i]}} tag=$1 } NR!=FNR { print }' yamlb yamla

解释:

awk 'NR==FNR && !/^[[:space:]]/ { # Processing yamlb (NR==FNR) and there there are spaces at the beginning of the line
         tag=$1; # Set the variable tag to the first space delimited field
         next # Skip to the next file
        } 
     tag=="rules:" && FNR==NR { # Process where tag is "rules:" and we are processing yamlb
          map[idx++]=$0 # Put the line in an array map with in incrementing index
        } 
     END { 
          tag="" # At the end of the file reset the variable tag
        } 
     NR!=FNR && !/^[[:space:]]/ { # Process yamla where there are no spaces at the start of the line
          if (tag=="rules:") { 
            for (i in map) { 
               print map[i] # If tag is equal to rules: print the array map
            }
          } 
          tag=$1 # Set the variable tag to the first space delimited field.
         } 
      NR!=FNR { 
          print # Print lines when we are processing yamla
         }' yamlb yamla

 

【讨论】:

  • 谢谢!这真的很酷 - 最后我能够使用 sed 和 yq 的组合来解决模板值,感谢您抽出时间来写这个,因为阅读和尝试很有趣。 :)
猜你喜欢
  • 2019-08-24
  • 2021-12-25
  • 1970-01-01
  • 2014-07-28
  • 2019-05-26
  • 2020-07-30
  • 1970-01-01
  • 2010-10-23
相关资源
最近更新 更多