如何使用 jq 遍历 Nagios JSON

How to use jq to iterate through Nagios JSON

我想弄清楚如何解析以下 JSON 而不必在多个命令中显式指示数组索引。我只需要在一行中将主机组与所有主机信息相关联。

{
  "data": {
    "selectors": {
    },
    "hostgroups": [
      {
        "name": "ATL",
        "hosts": [
          {
            "name": "ATL-SERVER1",
            "time_up": 2496629,
            "time_down": 8970,
            "time_unreachable": 0,
            "scheduled_time_up": 0,
            "scheduled_time_down": 0,
            "scheduled_time_unreachable": 0,
            "time_indeterminate_nodata": 0,
            "time_indeterminate_notrunning": 0
          },
          {
            "name": "ATL-SERVER2",
            "time_up": 2505525,
            "time_down": 74,
            "time_unreachable": 0,
            "scheduled_time_up": 0,
            "scheduled_time_down": 0,
            "scheduled_time_unreachable": 0,
            "time_indeterminate_nodata": 0,
            "time_indeterminate_notrunning": 0
          }
        ]
      },
      {
        "name": "LAX",
        "hosts": [
          {
            "name": "LAX-SERVER1",
            "time_up": 2505599,
            "time_down": 0,
            "time_unreachable": 0,
            "scheduled_time_up": 0,
            "scheduled_time_down": 0,
            "scheduled_time_unreachable": 0,
            "time_indeterminate_nodata": 0,
            "time_indeterminate_notrunning": 0
          },
          {
            "name": "LAX-SERVER2",
            "time_up": 2505599,
            "time_down": 0,
            "time_unreachable": 0,
            "scheduled_time_up": 0,
            "scheduled_time_down": 0,
            "scheduled_time_unreachable": 0,
            "time_indeterminate_nodata": 0,
            "time_indeterminate_notrunning": 0
          }
        ]
      }
    ]
  }
}

以下命令会得到我需要的东西:

.data.hostgroups[0].name as $Group | {$Group} + .data.hostgroups[0].hosts[] | [.Group, .name, .time_up, .time_down, .time_unreachable, .scheduled_time_up, .scheduled_time_down, .scheduled_time_unreachable, .time_indeterminate_nodata, .time_indeterminate_notrunning] | @csv
.data.hostgroups[1].name as $Group | {$Group} + .data.hostgroups[1].hosts[] | [.Group, .name, .time_up, .time_down, .time_unreachable, .scheduled_time_up, .scheduled_time_down, .scheduled_time_unreachable, .time_indeterminate_nodata, .time_indeterminate_notrunning] | @csv

但我一直在试图弄清楚如何在一行中做到这一点。我有 20 个主机组,所以我的脚本中有 20 个命令。

我发现的所有可比示例似乎都适用于仅从数组中拉出一个字段(在我的示例中是 host[])。例如,这可以正常工作:

map(.data.hostgroups | map({Group: .name, Host: .hosts[].name} | [.Group, .Host])) | add[] | @csv

输出为:

"ATL","ATL-SERVER1"
"ATL","ATL-SERVER2"
"LAX","LAX-SERVER1"
"LAX","LAX-SERVER2"

但是当我添加一个附加字段时,例如:

map(.data.hostgroups | map({Group: .name, Host: .hosts[].name, Uptime: .hosts[].time_up} | [.Group, .Host, .Uptime])) | add[] | @csv

输出为:

"ATL","ATL-SERVER1",2496629
"ATL","ATL-SERVER1",2505525
"ATL","ATL-SERVER2",2496629
"ATL","ATL-SERVER2",2505525
"LAX","LAX-SERVER1",2505599
"LAX","LAX-SERVER1",2505599
"LAX","LAX-SERVER2",2505599
"LAX","LAX-SERVER2",2505599

对于我添加的每个字段,基本上都是将它们相乘。而且我很确定我理解为什么会这样,但我仍在尝试弄清楚如何在避免以指数方式合并结果的问题的同时将其连成一行。

谁能帮帮我?

谢谢!

$ cat extract.jq
.data.hostgroups[]
| .name as $Group
| .hosts[]
| [$Group, .name, .time_up, .time_down, .time_unreachable,
   .scheduled_time_up, .scheduled_time_down, 
   .scheduled_time_unreachable, .time_indeterminate_nodata, 
   .time_indeterminate_notrunning]
| @csv


$ jq -r -f extract.jq in.json
"ATL","ATL-SERVER1",2496629,8970,0,0,0,0,0,0
"ATL","ATL-SERVER2",2505525,74,0,0,0,0,0,0
"LAX","LAX-SERVER1",2505599,0,0,0,0,0,0,0
"LAX","LAX-SERVER2",2505599,0,0,0,0,0,0,0