使用通配符从 jq 打印(或合并到第一个非空)

Vac*_*ano 8 json coalesce jq kubectl

我有以下命令:

kubectl get pod -A -o=json | jq -r '.items[]|select(any( .status.containerStatuses[]; .state.waiting or .state.terminated))|[.metadata.namespace, .metadata.name]|@csv'

这个命令效果很好。它输出失败 Pod 的命名空间和名称。

但现在我想在结果中再添加一列。我想要的列位于两个位置之一(且仅一个):

  • .status.containerStatuses[].state。等待原因
  • .status.containerStatuses[].state。终止.原因

我首先尝试添加.status.containerStatuses[].state.*.reason到结果字段数组中。但这给了我一个unexpected '*'编译错误。

然后我开始考虑如何使用 SQL 或其他编程语言来做到这一点。他们经常有一个函数返回其参数的第一个非空值。(这通常称为合并)。但是我找不到任何这样的命令jq

我如何返回reason查询结果?

pea*_*eak 11

jq 有一个与“coalesce”相对应的形式,形式为//. 例如,null // 0计算结果为 0,很可能它就足以满足您的情况,也许:

.status.containerStatuses[].state | (.waiting // .terminated) | .reason
Run Code Online (Sandbox Code Playgroud)

或者

.status.containerStatuses[].state | (.waiting.reason // .terminated.reason )
Run Code Online (Sandbox Code Playgroud)

或类似的。

但是,只能在对其用途有一定了解的情况下使用,如https://github.com/stedolan/jq/wiki/FAQ#or-versus-//上的 jq 常见问题解答中详细解释的那样

如果//由于某种原因不适用,那么明显的替代方案是一个if ... then ... else ... end语句,它与 C 的语句非常相似,_ ? _ : _因为它可以用来生成一个值,例如:

.status.containerStatuses[].state
| if has("waiting") then .waiting.reason
  else .terminated.reason
  end
Run Code Online (Sandbox Code Playgroud)

但是,如果containerStatuses是数组,则可能需要注意。