JQ中按前缀索引字符串数组

Index string array by prefix in JQ

我正在尝试弄清楚如何从中打印键的名称和特定的子子值。 我的 JSON 是:

{
  "results": 3,
  "rows": [
    {
      "hostname1": {
        "tags": [
          "owner:TEAM_A",
          "friendlyname:myhost1",
          "x:abc",
          "y:jkl"
        ]
      }
    },
    {
      "hostname2": {
        "tags": [
          "friendlyname:myhost2",
          "owner:TEAM_A",
          "x:def",
          "q:jkl"
        ]
      }
    },
    {
      "hostname3": {
        "tags": [
          "owner:TEAM_A",
          "x:ghi",
          "friendlyname:myhost3",
          "q:jkl"
        ]
      }
    }
  ]
}

我已经实现的是只打印主机名的键:

jq -r '.rows[] | keys[]' example.json
hostname1
hostname2
hostname3

我知道如何从标签数组打印 key:values:

jq -r .rows[0].hostname1.tags[0,1] example.json
owner:TEAM_A
friendlyname:myhost1

但是我不知道怎么打印

hostname1
          "owner:TEAM_A",
          "friendlyname:myhost1",
hostname2
          "owner:TEAM_A",
          "friendlyname:myhost2",
hostname3
          "owner:TEAM_A",
          "friendlyname:myhost3",

请注意,标签数组中的键有不同的顺序,所以我无法通过 .rows[0].hostname1.tags[0,1] 访问它我正在寻找类似 .rows[0].all_keys.tags[owner,friendlyname]

的东西

我的 bash 脚本非常接近,但键的顺序破坏了它。

hostnames=`jq -r '.rows[] | keys[]' example.json`
count=0
for i in $hostnames
do
   jq -r .rows[$count].$i\.tags[0,1] example.json
   echo $i
   ((count=count+1))
done

您可以使用 to_entries 将对象转换为 key-value 对的数组,然后根据自己的喜好访问其项目的 .key.value。例如:

jq -r '.rows[] | to_entries[] | [.key, .value.tags[0,1]] | join("\n ")'
hostname1
  owner:TEAM_A
  friendlyname:myhost1
hostname2
  friendlyname:myhost2
  owner:TEAM_A
hostname3
  owner:TEAM_A
  x:ghi

Demo

另一个例子:

jq -r '
  .rows[] | to_entries[] | [.key, (
    .value.tags[] | select(startswith("owner:", "friendlyname:"))
  )] | join("\n ")
'
hostname1
  owner:TEAM_A
  friendlyname:myhost1
hostname2
  friendlyname:myhost2
  owner:TEAM_A
hostname3
  owner:TEAM_A
  friendlyname:myhost3

Demo

首先将 tags 转换为对象将使按特定顺序检索标签变得更加容易。

.rows[][].tags | INDEX(sub(":.*"; "")) | .owner, .friendlyname

Online demo

似乎您不需要 shell 循环来完成这项任务,JQ 可以自己完成所有这些甚至更多。

.rows[]
| keys_unsorted[] as $hostname
| .[$hostname].tags
| INDEX(sub(":.*"; ""))
| $hostname, "\t" + (.owner, .friendlyname)

Online demo