缩短 kubectl jq 命令

问题描述 投票:0回答:1

我正在迭代

kubectl
输出,看起来与此类似:

{
  "apiVersion": "v1",
  "items": [
    {
      "kind": "Pod",
      "metadata": {
        "name": "ubuntu1",
        "namespace": "development-namespace1",
      },
   ],
    {
      "kind": "Pod",
      "metadata": {
        "name": "ubuntu2",
        "namespace": "development-namespace2",
      },
   ],
}

我正在尝试学习

jq
,但是我从第一本字典中获取值的命令真的很长:

kubectl get pods -o json -A | jq '.items | .[] | select(.metadata.name == "ubuntu1")  | .metadata.namespace'

我怎样才能缩短它?

json optimization jq
1个回答
0
投票
  • 这个答案假设:
    • Linux版本:Debian 12书虫
    • jq
      版本:
      1.6
    • Kubernetes 版本:
      1.28.3

迭代嵌套在以“items”为键的字典中的数组

使用从

kubectl get pods -o json -A
...

转储的这个(缩写)json 输出
{
  "apiVersion": "v1",
  "items": [
    {
      "kind": "Pod",
      "metadata": {
        "name": "ubuntu1",
        "namespace": "development-namespace1",
      },
   ],
    {
      "kind": "Pod",
      "metadata": {
        "name": "ubuntu2",
        "namespace": "development-namespace2",
      },
   ],
}

正如 @pmf 在评论中所说,您可以使用以下方法选择嵌套在该数组中的键的值:

jq '.items[] | select(.metadata.name == "ubuntu1").metadata.namespace'

说明

  • .items[]
    返回由
    items
  • 键控的数组
  • select(metadata.name == "ubuntu1")
    • 搜索所有字典
    • 查找与嵌套键:
      metadata.name
      和值:
      ubuntu1
    • 匹配的字典
  • select(.metadata.name == "ubuntu1").metadata.namespace
    返回所选字典中
    .metadata.namespace
    的值

重申一下,

jq '.items[] | select(metadata.name == "ubuntu1")
返回:

{
  "metadata": {
    "name": "ubuntu1",
    "namespace": "development-namespace1",
  }
}

额外材料,对任何带有列的 shell 命令使用 jq

解析“ps”输出

假设您要解析 ps 命令的输出...

假设

ps | <insert-sed-jq-pipe-here>
返回以下内容...

$ ps | <insert-sed-jq-pipe-here>
    PID TTY          TIME CMD
  11899 pts/0    00:00:18 bash
2694259 pts/0    00:00:00 ps
2694260 pts/0    00:00:00 sed
2694261 pts/0    00:00:00 jq
$

您可以使用以下方法将任何列式文本转换为 json:

jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]'

将 'ps' 输出解析为 json

此示例会将上述

ps
转储为 json...

$ ps | sed -ne '/PID/,$ p' | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]'
[
  [
    "PID",
    "TTY",
    "TIME",
    "CMD"
  ],
  [
    "11899",
    "pts/0",
    "00:00:18",
    "bash"
  ],
  [
    "2694259",
    "pts/0",
    "00:00:00",
    "ps"
  ],
  [
    "2694260",
    "pts/0",
    "00:00:00",
    "sed"
  ],
  [
    "2694261",
    "pts/0",
    "00:00:00",
    "jq"
  ]
]
$

将“top”输出解析为 json

您甚至可以在

top
上使用此技术...但是
top
乍一看有点棘手,因为:

  • 默认是交互式的
  • 您会在
    PID
    列标题之前获得额外的文本......示例:
$ top -bn 1 | head -n 8
top - 08:54:54 up 14 days,  1:13,  0 user,  load average: 0.11, 0.22, 0.30
Tasks:  96 total,   1 running,  95 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  6.7 sy,  0.0 ni, 93.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3767.1 total,    109.5 free,   2140.8 used,   1990.5 buff/cache
MiB Swap:   1024.0 total,    898.2 free,    125.8 used.   1626.4 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
2371290 root      20   0 1931856  48168  27024 S   6.7   1.2   0:30.64 flanneld
$

可以用

top
解决交互式
top -bn 1
问题,在非交互模式下会跑top一次。

最后,我们在

sed
命令中使用的相同
ps
将删除
top
PID
之前的行...所以最终的
top
命令作为 json 是:

$ top -bn 1 | sed -ne '/PID/,$ p' | jq -sR '[sub("\n$";"") | splits("\n") | sub("^ +";"") | [splits(" +")]]'

... insert-top-json-output-here
$
© www.soinside.com 2019 - 2024. All rights reserved.