有输入
- groupx:
- groupy:
yq 表达式
length
计算为 2
有输入
groupx:
groupy:
yq 表达式
length
also 计算为 2
.[]
) 将 case1 转换为 case2首先,我们将案例 1 的输入转换为案例 2:
$ yq '.[]' case1.yaml
groupx:
groupy:
我们注意到这与
case2.yaml
的输出相同
如果我想用 case2 的表达式扩展这个表达式,我不会得到相同的输出,而是得到以下结果:
$ yq '.[] | length' case1.yaml
1
1
如果我添加第二个 yq 过程,我 do 会得到与 case2 相同的结果:
$ yq '.[]' case1.yaml | yq 'length'
2
为什么 yq 的 splat 运算符使结果有效地成为 yaml 多文档?这没有意义,因为相同的输出再次作为 yq 的输入,不会产生多文档。
如果这是预期行为,您可以在使用
.[]
后返回到单个文档而不启动新的 yq 流程吗?
案例 1 是一个带有 seq(数组)的单个文档,其中包含两个映射(对象),每个映射都只有一个键(字段)。
案例 2 是一个带有映射(对象)的单个文档,其中包含两个键(字段)。
将
.[]
应用于任何一种情况都会破坏文档的顶级类型(第一种情况下的 seq,第二种情况下的映射),并在 two 文档中产生结果(对于这两种情况)(第一个有两个映射,第二个有两个映射)第二个两个(空)值)。
因此,在同一个过滤器中将
length
应用于该结果总是会产生两个数字(在第一种情况下都是 1
,因为你有两个映射,每个映射都包含一个键,而在第二种情况下,两个 0
因为你有两个标量不包含任何内容的值)。
但是,将
length
应用于另一个过滤器中的结果会重新评估输入。现在,在第一种情况下,两个单项映射折叠成一个包含两个项的映射,因此总体结果为 2
。在第二种情况下,标量值无法进一步折叠,因此结果保持不变(两个数字,都是 0
)。
无论这是有意还是无意,我都无法代表开发商发言。但我可以断言,这种偏差仅适用于 mikefarah/yq,不适用于 kislyuk/yq,后者始终将输入视为两个文档,因为它主动打印文档分隔符。 (虽然 mikefarah/yq 有一个
--no-doc
(或 -N
)选项“不打印文档分隔符”,但这似乎是默认应用的——使用版本 v4.34.2 和 v4.40.5 进行测试)。
如果这是预期行为,您可以在使用
后返回到单个文档而不启动新的 yq 流程吗?.[]
当然。您可以将解构后的项目收集为单个项目,但其实现取决于它应该具有什么类型。
如果您希望它是结果文档的序列,请将过滤器括在括号中以将项目收集到其中。所以
.[] | … | length
将变成 [.[] | …] | length
并且应该产生 2
。实际上,您可以使用 [.[] | …]
快捷方式 map(…)
。
如果您希望它成为一个地图(就像它通过两次调用折叠一样),您可以使用
ireduce
迭代地将所有项目附加到最初为空的地图:(.[] | …) as $i ireduce ({}; . + $i) | length
。 (旁注:使用 kislyuk/yq,您可以使用 add
过滤器,可以将一系列映射折叠成单个映射。)