如何扁平化YAML结构(List/Map)

问题描述 投票:0回答:1

是否可以将分层属性(地图/列表)转换为扁平化为线性

YAML
结构?

例如,微服务中定义了以下属性:

default:  
  app:
    authentication: 
      security: ${app.authentication.security}

可以使用

kube
对象(即 configMap)覆盖上面的内容,并且上面的属性公开为
${app.authentication.security}
,所以在
configMap
内部我们不需要定义整个结构(如下所示),所以这里我们受宠若惊
YAML
层次结构。我们不需要定义整个订单。

app.authentication.security: false 

现在,是否有可能使

YAML
地图/列表变得更漂亮,并且那些
Map/List
属性可以是动态的。以下是示例结构。

示例:

app-ex:
  list: 
    - key1: value
      key2: value
      key3: 
        - list1
        - list2
        - list3
    - key4: value
      key5: value
      key6: 
        - list1
        - list2
        - list3
    .
    .
    - key N

可能的预期输出可以是如下平坦模式:

app-ex.list.key1: val1
app-ex.list.key2: val2
kubernetes yaml microservices kubernetes-helm spring-cloud-config
1个回答
3
投票

YAML 处理器可以轻松处理和操作此类文件。以下是一些示例:

  • 使用 kislyuk/yq(在 jq 1.6+ 上运行)使用
    --stream
    标志或
    tostream
    函数来生成路径值对数组,使用
    select
    来过滤它们的叶子,并使用
    add
    来生成输出对象:
yq -sy --stream 'map(select(has(1)) | {(first | join(".")): last}) | add' file.yaml
# or
yq -y '[tostream | select(has(1)) | {(first | join(".")): last}] | add' file.yaml

注意:在 jq 1.5 上运行时,使用

first | map(@text) | join(".") …

转换为字符串
  • 使用 itchyny/gojq 调整参数以及上面的后一个过滤器:
gojq --yaml-input --yaml-output '[tostream | select(has(1)) | {(first | join(".")): last}] | add' file.yaml
  • 使用 mikefarah/yq (v4.18.1+) 使用
    ..
    递归下降,
    select
    过滤叶值,以及
    path
    检索路径:
yq '.. | select(tag != "!!seq" and tag != "!!map") | {path | join("."): .}' file.yaml

注意:对于 v4.18.1 之前的版本,必须提供

eval
(或
e
)命令,例如
yq e '…' file.yaml
。此外,对于 v4.6.2 之前的版本,将键表达式括在括号中,如
… | {(path | join(".")): .}
所示,对于 v4.5.1 之前的版本,使用
select((tag == "!!seq" or tag == "!!map") | not)
过滤叶值。

输出示例:

app-ex.list.0.key1: value
app-ex.list.0.key2: value
app-ex.list.0.key3.0: list1
app-ex.list.0.key3.1: list2
app-ex.list.0.key3.2: list3
app-ex.list.1.key4: value
app-ex.list.1.key5: value
app-ex.list.1.key6.0: list1
app-ex.list.1.key6.1: list2
app-ex.list.1.key6.2: list3

注意:其他地方提出的一些较短的方法在某些边缘情况下会失败,包括使用

select(. == "*")
与 mikefarah/yq 忽略
null
值,以及使用
leaf_paths
paths(scalars)
与 kislyuk/yq 和 itchyny/gojq既不捕获
null
也不捕获
false
值。

© www.soinside.com 2019 - 2024. All rights reserved.