使用通配符从 jq 打印(或合并到第一个非空值)
Print from jq using a wild card (or coalesce to first non null)
我有以下命令:
kubectl get pod -A -o=json | jq -r '.items[]|select(any( .status.containerStatuses[]; .state.waiting or .state.terminated))|[.metadata.namespace, .metadata.name]|@csv'
这个命令效果很好。它输出我失败的命名空间和名称 pods.
但现在我想在结果中再添加一列。我想要的列位于两个位置之一(并且只有一个):
- .status.containerStatuses[].state.正在等待.reason
- .status.containerStatuses[].state.终止.原因
我首先尝试将 .status.containerStatuses[].state.*.reason
添加到结果字段数组。但这给了我一个 unexpected '*'
编译错误。
然后我开始考虑如何使用 SQL 或其他编程语言来做到这一点。他们经常有一个函数将 return 其参数的第一个非空值。 (这通常称为合并)。但是我找不到 jq
.
的任何此类命令
我怎样才能 return reason
作为我查询的结果?
jq 以 //
的形式对应于“合并”。
例如,null // 0
的计算结果为 0,很可能在您的情况下就足够了,也许:
.status.containerStatuses[].state | (.waiting // .terminated) | .reason
或
.status.containerStatuses[].state | (.waiting.reason // .terminated.reason )
或类似。
但是,//
只能在对它的作用有所了解的情况下使用,如 https://github.com/stedolan/jq/wiki/FAQ#or-versus-
的 jq FAQ 中的详细解释
如果 //
由于某种原因不适用,那么明显的替代方法是 if ... then ... else ... end
语句,这与 C 的 _ ? _ : _
非常相似,因为它可用于生成值,例如类似于:
.status.containerStatuses[].state
| if has("waiting") then .waiting.reason
else .terminated.reason
end
但是,如果 containerStatuses
是数组,则可能需要注意一些。
如果您想使用 coalesce
:
# Stream-oriented version
def coalesce(s):
first(s | select(. != null)) // null;
或者如果您更喜欢使用数组:
# Input: an array
# Output: the first non-null element if any, else null
def coalesce: coalesce(.[]);
使用面向流的版本,您可以使用通配符按照您的想法编写一些内容,例如
coalesce(.status.containerStatuses[].state[].reason?)
我有以下命令:
kubectl get pod -A -o=json | jq -r '.items[]|select(any( .status.containerStatuses[]; .state.waiting or .state.terminated))|[.metadata.namespace, .metadata.name]|@csv'
这个命令效果很好。它输出我失败的命名空间和名称 pods.
但现在我想在结果中再添加一列。我想要的列位于两个位置之一(并且只有一个):
- .status.containerStatuses[].state.正在等待.reason
- .status.containerStatuses[].state.终止.原因
我首先尝试将 .status.containerStatuses[].state.*.reason
添加到结果字段数组。但这给了我一个 unexpected '*'
编译错误。
然后我开始考虑如何使用 SQL 或其他编程语言来做到这一点。他们经常有一个函数将 return 其参数的第一个非空值。 (这通常称为合并)。但是我找不到 jq
.
我怎样才能 return reason
作为我查询的结果?
jq 以 //
的形式对应于“合并”。
例如,null // 0
的计算结果为 0,很可能在您的情况下就足够了,也许:
.status.containerStatuses[].state | (.waiting // .terminated) | .reason
或
.status.containerStatuses[].state | (.waiting.reason // .terminated.reason )
或类似。
但是,//
只能在对它的作用有所了解的情况下使用,如 https://github.com/stedolan/jq/wiki/FAQ#or-versus-
如果 //
由于某种原因不适用,那么明显的替代方法是 if ... then ... else ... end
语句,这与 C 的 _ ? _ : _
非常相似,因为它可用于生成值,例如类似于:
.status.containerStatuses[].state
| if has("waiting") then .waiting.reason
else .terminated.reason
end
但是,如果 containerStatuses
是数组,则可能需要注意一些。
如果您想使用 coalesce
:
# Stream-oriented version
def coalesce(s):
first(s | select(. != null)) // null;
或者如果您更喜欢使用数组:
# Input: an array
# Output: the first non-null element if any, else null
def coalesce: coalesce(.[]);
使用面向流的版本,您可以使用通配符按照您的想法编写一些内容,例如
coalesce(.status.containerStatuses[].state[].reason?)