【问题标题】:jq: list users belonging to a specific group in arrayjq:列出属于数组中特定组的用户
【发布时间】:2021-11-23 08:14:24
【问题描述】:

输入json:

[
  {
    "user": "u1"
  },
  {
    "user": "u2",
    "groups": [
      {
        "id": "100001",
        "name": "G1"
      },
      {
        "id": "100002",
        "name": "G2"
      }
    ]
  },
  {
    "user": "u3",
    "groups": [
      {
        "id": "100001",
        "name": "G1"
      }
    ]
  }
]

我想查找属于特定组的所有用户(在groups 数组中按组name 或组id 搜索)

$ jq -r '.[]|select(.groups[].name=="G1" | .user)' json
jq: error (at json:27): Cannot iterate over null (null)

搜索示例组 G1 时所需的输出格式为:

u2
u3

补充问题: 是否可以在不使用 tr 等外部实用程序的情况下生成逗号分隔的输出 u2,u3

【问题讨论】:

  • 你想要的输出格式是什么?

标签: jq


【解决方案1】:

如果两个输入匹配,最好使用--arg 从参数中输入您的搜索数据并使用any 以避免重复输出:

jq -r --arg id "" --arg name "G1" '
  .[] | select(.groups | map(.id == $id or .name == $name) | any)? | .user
'
u2
u3

Demo

【讨论】:

  • 这样 OP 可以使用例如集成这个 sn-p --arg id "${id}" --arg name "${name}" 并且不必担心哪个实际具有搜索数据。当然,如果 OP 的“按组名或组 id”搜索问题是为了使实现更容易,但实际上只需要一个,那么一个就足够了。 -- 最后,过滤器内部的所有变量也必须在外部声明。
【解决方案2】:

使用? 作为Optional Object Identifier-Index 运算符,您可以进行如下选择

map(select(.groups[].name == "G1")? | .user)

并在过滤器末尾使用[] 解包数组中的结果。要组合多个选择条件,请在 select 语句中使用 boolean operatorsand/or

在 jqplay 上查看demo

【讨论】:

  • 我终于使用以下命令来生成逗号分隔的列表。是否可以避免外部命令并通过 jq 生成这样的列表? jq -r 'map(select(.groups[].name == "LSY")? | .user)|@tsv'|tr -s '\t' ','
  • @Chris 使用@csv 而不是@tsv。这会直接为您提供逗号而不是制表符(之后您不必调用 tr
  • @pmf 谢谢,当我使用@csv 时还有一个问题我们的输入是带引号的,所以我需要再次使用tr -d \"
  • @Chris 那是因为 CSV 需要它。但是您可以构建自己的格式,例如join(",") 使用元素之间的给定分隔符字符串(在本例中为逗号)将数组的字符串元素连接到更大的字符串。但请注意,当涉及转义“特殊”内容时(例如,如果值本身包含逗号等),您将自己离开。
猜你喜欢
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 2018-11-18
  • 2011-07-14
  • 2016-07-18
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
相关资源
最近更新 更多