使用jq工具将嵌套的数组展开,并转换为多个对象

我因为想在jq中做以下事情而纠结了一下,最终想出了一个方法,做个备忘录。

我想做的事情

使用中文来重新表达这个含有以下数组的对象

{
  "pod": {
    "name": "mypod"
  },
  "containers": [
    {
      "name": "mycontainer1",
      "usage": {
            "cpu": "50"
          }
    },
    {
      "name": "mycontainer2",
      "usage": {
            "cpu": "100"
          }
    }
  ]
}

我想把以下这样的多个对象实现。

{
  "pod_name": "mypod",
  "container_name": "mycontainer1",
  "container_cpu": "50"
}
{
  "pod_name": "mypod",
  "container_name": "mycontainer2",
  "container_cpu": "100"
}

办法

在jq手册的对象构造部分有解释,可以创建一个新的对象,并通过对containers数组进行解包([])来将其展开为不同的对象。

嵌套数组的展开

cat sample.json | \
  jq '{
        pod,
        container: .containers[]
      }'
{
  "pod": {
    "name": "mypod"
  },
  "container": {
    "name": "mycontainer1",
    "usage": {
      "cpu": "50"
    }
  }
}
{
  "pod": {
    "name": "mypod"
  },
  "container": {
    "name": "mycontainer2",
    "usage": {
      "cpu": "100"
    }
  }
}

(补充)pod的部分采用省略形式,直接传递原始字段,但也可以适当地进行详细描述。

cat sample.json | \
  jq '{
        pod: { name: .pod.name },
        container: .containers[]
      }'

创建对象

从展开的结果中挑选出所需信息,并创建一个新的对象。

cat sample.json | \
  jq '{
        pod,
        container: .containers[]
      } |
      {
        pod_name: .pod.name,
        container_name: .container.name,
        container_cpu: .container.usage.cpu
      }'
{
  "pod_name": "mypod",
  "container_name": "mycontainer1",
  "container_cpu": "50"
}
{
  "pod_name": "mypod",
  "container_name": "mycontainer2",
  "container_cpu": "100"
}

注意事项

直接创建对象而不通过中间对象会导致结果变成乘法,并且对象的数量会增加。

cat sample.json | \
  jq '{
        pod_name: .pod.name,
        container_name: .containers[].name,
        container_cpu: .containers[].usage.cpu
       }'
{
  "pod_name": "mypod",
  "container_name": "mycontainer1",
  "container_cpu": "50"
}
{
  "pod_name": "mypod",
  "container_name": "mycontainer1",
  "container_cpu": "100"
}
{
  "pod_name": "mypod",
  "container_name": "mycontainer2",
  "container_cpu": "50"
}
{
  "pod_name": "mypod",
  "container_name": "mycontainer2",
  "container_cpu": "100"
}

不经过中间对象,直接创建数组会导致原始数组的元素按照原样排列。

cat sample.json | \
  jq '[
        .pod.name,
        .containers[].name,
        .containers[].usage.cpu
       ]'
[
  "mypod",
  "mycontainer1",
  "mycontainer2",
  "50",
  "100"
]

給你额外的东西。

原本想做的事情是从Kubernetes的Metric API获取类似以下的JSON,然后将其转换为CSV格式。以下是IBM Cloud Private v3.1.2的情况。

{
  "kind": "PodMetricsList",
  "apiVersion": "metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/metrics.k8s.io/v1beta1/pods"
  },
  "items": [
    {
      "metadata": {
        "name": "audit-logging-fluentd-ds-pgp88",
        "namespace": "kube-system",
        "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/audit-logging-fluentd-ds-pgp88",
        "creationTimestamp": "2019-04-10T01:22:42Z"
      },
      "timestamp": "2019-04-10T01:22:17Z",
      "window": "30s",
      "containers": [
        {
          "name": "fluentd",
          "usage": {
            "cpu": "2513099n",
            "memory": "62276Ki"
          }
        }
      ]
    },

(以下略)

获取令牌

在使用cloudctl login进行登陆后,使用cloudctl tokens获取令牌。

ID_TOKEN=$(LANG=C cloudctl tokens | grep "ID token:" | awk '{print $3}')

通过度量API获取数据

用 curl 获取 JSON 数据并将其存入变量中。

CLUSTER="mycluster.icp"
JSON=$(curl -s -k -H "Authorization: Bearer ${ID_TOKEN}" \
  "https://${CLUSTER}:8001/apis/metrics.k8s.io/v1beta1/pods" \
  | jq -c '.')

使用jq将JSON转换为CSV。

使用jq将数组展开为多个对象并创建中间数据,然后从中选择所需的数据并将其分别组成数组,再使用@csv将其转换为csv格式。最后,使用rtrimstr(str)函数去除单位。

echo $JSON | \
  jq -r '.items[] |
          {
            metadata,
            timestamp,
            container: .containers[]
          } |
          [
            .timestamp,
            .metadata.namespace,
            .metadata.name,
            .container.name,
            ( .container.usage.cpu | rtrimstr("n") ),
            ( .container.usage.memory | rtrimstr("Ki") )
          ] | @csv'
"2019-04-10T02:35:25Z","kube-system","monitoring-prometheus-collectdexporter-57b8c6ff5c-dclw4","collectd-exporter","1488183","11416"
"2019-04-10T02:35:25Z","kube-system","monitoring-prometheus-collectdexporter-57b8c6ff5c-dclw4","router","54112","4532"
"2019-04-10T02:35:09Z","kube-system","logging-elk-filebeat-ds-2x49r","filebeat","4745057","28692"
"2019-04-10T02:35:20Z","kube-system","monitoring-prometheus-elasticsearchexporter-7f5967f56-d68sd","router","12534","8312"
"2019-04-10T02:35:20Z","kube-system","monitoring-prometheus-elasticsearchexporter-7f5967f56-d68sd","elasticsearchexporter","3207930","13132"
"2019-04-10T02:35:10Z","kube-system","k8s-etcd-9.188.124.130","etcd","50751515","261432"

(以下略)
广告
将在 10 秒后关闭
bannerAds