是否可以将分层属性(地图/列表)转换为扁平化为线性
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
YAML 处理器可以轻松处理和操作此类文件。以下是一些示例:
--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(".") …
转换为字符串
gojq --yaml-input --yaml-output '[tostream | select(has(1)) | {(first | join(".")): last}] | add' file.yaml
..
递归下降,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
值。