2016-03-02 61 views
1

我想弄清楚如何解析下面的JSON,而不必明确指出多个命令中的数组索引。我只需要将主机组与所有主机信息关联在一行上。如何使用jq遍历Nagios 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个命令。

我发现的所有可比较的例子似乎只适用于从数组中拉出单个字段(在我的例子中它是主机[])。例如,这将很好地工作:

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 

对于每个字段I a dd,它基本上将它们相乘。我很确定我明白这是为什么,但我仍然试图弄清楚如何排除这种情况,同时避免将结果以指数方式组合的问题。

任何人都可以帮我吗?

谢谢!

回答

1
$ 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 
+0

非常感谢。它对我有效,我明白为什么现在这是必要的。我明白了| .host []正常运行,我明白现在循环是如何工作的。非常感谢! –