【问题标题】:How to spare & group objects according key-value如何根据键值对对象进行备用和分组
【发布时间】:2021-12-29 17:00:24
【问题描述】:

我是新手,这是我的第一步。我想我是从一个不简单的案例开始的。

让我们看看: 我有具有 ID (name) 和资源组 (rgs) 的对象。每个对象可能是几个组的一部分。而真正需要的是获得组的交集。

重要的是说对象可能是几个组的一部分,这些组是父子组,我只需要获取父组。由于他们共享前缀,因此很容易识别父母身份。

例如组 PROM_FD_ARCNA 包含子组 PROM_FD_ARCNA_TGMPROM_FD_ARCNA_TGM_TGA。 子组包含对象本身。但是,只要我能从 object 中获取信息,就结束了。

父组是PROM_FD_ARCNAPROM_JOB_ICMPPROM_JOB_WIN。也就是说,我需要获取那些属于这些组的交集的对象。

JSON 文件如下所示:

[
    {
        "id_ci": "487006",
        "name": "LABTNSARWID625",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGM, PROM_FD_ARCNA_TGM_TGA"
    },
    {
        "id_ci": "5706",
        "name": "HCCQ2001",
        "id_ci_class": "host",
        "rgs": "PROM_JOB_ICMP"
    },
    {
        "id_ci": "9106",
        "name": "HCC02155",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_ICMP"
    },
    {
        "id_ci": "2306",
        "name": "VM00006",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_WIN, PROM_JOB_WIN_TGA"
    }
]

如果我的解释不好,我需要得到这样的 JSON:

PROM_FD_ARCNA, PROM_JOB_ICMP
{
"HCC02155"
}

PROM_FD_ARCNA, PROM_JOB_WIN 
{
"VM00006"
}

因为那些是十字路口。


到目前为止,我试过这个:

jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_FD_ARCNA")) | .rgs = "PROM_FD_ARCNA"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json 
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_WIN")) | .rgs = "PROM_JOB_WIN"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json 
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_ICMP")) | .rgs = "PROM_JOB_ICMP"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json

结果是:

[
  {
    "rgs": "PROM_FD_ARCNA",
    "Hosts": [
      "LABTNSARWID625",
      "HCC02155",
      "VM00006"
    ]
  }
]
[
  {
    "rgs": "PROM_JOB_WIN",
    "Hosts": [
      "VM00006"
    ]
  }
]
[
  {
    "rgs": "PROM_JOB_ICMP",
    "Hosts": [
      "HCCQ2001",
      "HCC02155"
    ]
  }
]

当然,完整的 JSON 很长,我需要尽可能轻量级地处理它。不知道我的开始是好是坏。

【问题讨论】:

  • Re "我需要得到这样的 JSON:",这甚至不接近有效的 JSON

标签: json jq


【解决方案1】:
def to_set(s): reduce s as $_ ( {}; .[ $_ ] = true );

[ "PROM_FD_ARCNA", "PROM_JOB_ICMP", "PROM_JOB_WIN" ] as $roots |

map(
   {
      name,
      has_rg: to_set( .rgs | split( ", " )[] )
   }
) as $hosts |

[
   range( 0;    $roots | length ) as $i |  $roots[ $i ] as $g1 |
   range( $i+1; $roots | length ) as $j |  $roots[ $j ] as $g2 |
   {
      root_rgs: [ $g1, $g2 ],
      names: [
         $hosts[] |
         select( .has_rg[ $g1 ] and .has_rg[ $g2 ] ) |
         .name
      ]
   } |
   select( .names | length > 0 )
]

生产

[
  {
    "root_rgs": [
      "PROM_FD_ARCNA",
      "PROM_JOB_ICMP"
    ],
    "names": [
      "HCC02155"
    ]
  },
  {
    "root_rgs": [
      "PROM_FD_ARCNA",
      "PROM_JOB_WIN"
    ],
    "names": [
      "VM00006"
    ]
  }
]

Demojqplay

【讨论】:

  • 可以使用INDEX( …; . ) 代替to_set( … )
  • [ $g1, $g2 ] 替换为"\( $g1 ), \( $g2 )" 以获得与输入相同的格式。
猜你喜欢
  • 2021-04-12
  • 2017-09-29
  • 2018-11-23
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多