【问题标题】:JQ: A list with multiple values for one keyJQ:一个键有多个值的列表
【发布时间】:2021-12-20 10:34:13
【问题描述】:

使用 jq,我想获取应用程序名称、所有版本和服务器名称的列表。该列表不应包含有关最新版本的信息。

输入:

{
  "software": {
    "app_1": {
      "0.0.1": {
        "properties_1": {
          "lang": "en"
        },
        "server": "vm123-4.domain.com"
      },
      "0.0.2": {
        "properties_2": {
          "arch": "x86"
        },
        "server": "vm123-5.comain.com"
      },
      "latest_version": "0.0.2"
    },
    "app_2": {
      "1.0.1": {
        "properties_2": {
          "arch": "x86"
        },
        "server": "vm333-1.domain.com"
      },
      "latest_version": "1.0.1"
    },
    "app_33": {
      "0.44.1": {
        "properties_1": {
          "lang": "en"
        },
        "properties_2": {
          "arch": "x86"
        },
        "properties_3": {
          "boot": "true"
        },
        "server": "vm888-9.domain.com"
      },
      "1.2.2": {
        "properties_3": {
          "boot": "yes"
        },
        "server": "vm123-4.domain.com"
      },
      "latest_version": "1.2.2"
    }
  }
}

期望的输出:

"app_1,  0.0.1,  vm123-4.domain.com"
"app_1,  0.0.2,  vm123-5.comain.com"
"app_2,  1.0.1,  vm333-1.comain.com"
"app_33, 0.44.1, vm888-9.comain.com"
"app_33, 1.2.2,  vm123-4.comain.com"

我的请求将只列出应用程序的一个版本,但不是全部。我不知道该怎么做。

.software | to_entries[] | [(.key), (.value | to_entries[] | select(.key | IN("latest_version") | not))] | "\(.[0]) \(.[1].key) \(.[1].value.server)"

我的输出:

"app_1  0.0.1  vm123-4.domain.com"
"app_2  1.0.1  vm333-1.domain.com"
"app_33 0.44.1 vm888-9.domain.com"

【问题讨论】:

  • 您能否编辑问题以显示您如何获得第一个 Output,以及所需的结果集是什么?
  • 需要第一个输出,我得到的最后一个。
  • 但您的问题表明“列表不应包含有关最新版本的信息。”。那么为什么包含 app1 0.0.2 和 app2 1.0.1 呢?
  • 列表不应包含“latest_version”键。此键与 app_1 0.0.2、app_2 1.0.1 等处于同一级别。列表应仅包含“请求输出”数据。

标签: jq


【解决方案1】:
.software | to_entries[] | "\(.key) \(.value | to_entries[] | select(.key != "latest_version") | "\(.key) \(.value.server)")"

会产生

"app_1 0.0.1 vm123-4.domain.com"
"app_1 0.0.2 vm123-5.comain.com"
"app_2 1.0.1 vm333-1.domain.com"
"app_33 0.44.1 vm888-9.domain.com"
"app_33 1.2.2 vm123-4.domain.com"

你可以测试in this online demo


使用--raw-output 和标签\t,我们可以创建一个类似于输出的列:

app_1   0.0.1   vm123-4.domain.com
app_1   0.0.2   vm123-5.comain.com
app_2   1.0.1   vm333-1.domain.com
app_33  0.44.1  vm888-9.domain.com
app_33  1.2.2   vm123-4.domain.com

Demo

【讨论】:

  • 感谢@Ostone0 的解决方案。效果很好!
【解决方案2】:
jq -r '.software | to_entries[] | .key as $app | .value | to_entries[] | select((.value | objects)) |  [$app, .key, .value.server] | @csv'

【讨论】:

  • 感谢@Botje 的解决方案。我改变了:[$app, .key, .value.server] | @csv on "\($app), \(.key), \(.value.server)"
  • @Ege: 或将@csv 替换为@tsv
猜你喜欢
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 2020-07-21
  • 1970-01-01
相关资源
最近更新 更多