一个叫木头,一个叫马尾

jq的两个特殊用法示例

jq 大概是我最爱用的JSON处理工具了,今天介绍其两个用法。


嵌套对象合并

已知入参:

{"a":1,"b":{"c":2,"d":3}}

如何得到的下面结果:

{"a":1,"c":2,"d":3}

答案:

echo '{"a":1,"b":{"c":2,"d":3}}' |
jq '.+.b | del(.b)'

解释:

  1. .表示根对象;
  2. .b 表示 b 所在的子对象;
  3. +用于将两个对象合并,
  4. 合并后要将原先的 b 对象删除,故使用 del(.b)

嵌套数组和外层对象合并

已知入参:

{
  "a"1,
  "b": [{"c":2},{"d":3}]
}

如何得到:

[
  {"a":1,"c":2},
  {"a":1,"d":3}
]

答案:

echo '{"a":1,"b":[{"c":2},{"d":3}]}' |
jq '{a} as $a | .b | map($a+.)'

解释:

  1. 先用变量 $a 捕获 {"a":1}
  2. 再遍历 b 所在的数组,对于每个数组元素,返回一个新的由该元素和$a合并后的元素

实战

咱不能光说不练,举个具体用途。

对于Kubernetes来说,k get po -o json 会返回所有pod的配置详情,其信息量比较大:

以JSON格式列出k8s下所有pod信息
以JSON格式列出k8s下所有pod信息

如果我们只想得到pod的名称、容器的名称和镜像地址,怎么办?

jq 来帮忙,将需要的数据从原始JSON中筛选出来即可。

k get po -o json | jq '
.items 
| map(
  .metadata.name as $pod 
  | .spec.containers 
  | map( {pod: $pod,name,image} )

| flatten'

最终得到了这样的结果:

使用jq格式化kubectl输出
使用jq格式化kubectl输出

是不是很赞!