Восстановление JSON с помощью jq - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть такой JSON (sample.json):

{
  "sheet1": [
    {
      "hostname": "sv001",
      "role": "web",
      "ip1": "172.17.0.3"
    },
    {
      "hostname": "sv002",
      "role": "web",
      "ip1": "172.17.0.4"
    },
    {
      "hostname": "sv003",
      "role": "db",
      "ip1": "172.17.0.5",
      "ip2": "172.18.0.5"
    }
  ],
  "sheet2": [
    {
      "hostname": "sv004",
      "role": "web",
      "ip1": "172.17.0.6"
    },
    {
      "hostname": "sv005",
      "role": "db",
      "ip1": "172.17.0.7"
    },
    {
      "hostname": "vsv006",
      "role": "db",
      "ip1": "172.17.0.8"
    }
  ],
  "sheet3": []
}

Я хочу извлечь данные следующим образом:

sheet1

jq '(что-то команда) 'sample.json

{
    "web": {
        "hosts": [
            "172.17.0.3",
            "172.17.0.4"
        ]
    },
    "db": {
        "hosts": [
            "172.17.0.5"
        ]
    }
}

Можно ли выполнить реконструкцию с помощью jq map?(Я буду повторно использовать результат для инвентаризации.)

Ответы [ 2 ]

1 голос
/ 21 сентября 2019

Вот короткое, прямолинейное и эффективное решение - отчасти эффективное, поскольку оно избегает group_by благодаря следующей универсальной вспомогательной функции:

def add_by(f;g): reduce .[] as $x ({}; .[$x|f] += [$x|g]);
.sheet1
| add_by(.role; .ip1) 
| map_values( {hosts: .} )

Вывод

Это дает требуемый результат:

{
 "web": {
    "hosts": [
      "172.17.0.3",
      "172.17.0.4"
    ]
  },
  "db": {
    "hosts": [
      "172.17.0.5"
    ]
  }
}
0 голосов
/ 21 сентября 2019

Если цель состоит в том, чтобы перегруппировать ips по их ролям на каждом листе, вы можете сделать это:

map_values(
    reduce group_by(.role)[] as $g ({};
        .[$g[0].role].hosts = [$g[] | del(.hostname, .role)[]]
    )
)

, что приводит к примерно так:

{
  "sheet1": {
    "db": {
      "hosts": [
        "172.17.0.5",
        "172.18.0.5"
      ]
    },
    "web": {
      "hosts": [
        "172.17.0.3",
        "172.17.0.4"
      ]
    }
  },
  "sheet2": {
    "db": {
      "hosts": [
        "172.17.0.7",
        "172.17.0.8"
      ]
    },
    "web": {
      "hosts": [
        "172.17.0.6"
      ]
    }
  },
  "sheet3": {}
}

https://jqplay.org/s/3VpRc5l4_m

Если вы хотите свести все к одному объекту, сохраняя только уникальные ips, вы можете оставить все в основном одинаковыми, вам просто нужно сгладить входные данные перед группировкой и удалить вызов map_values/1.

$ jq -n '
reduce ([inputs[][]] | group_by(.role)[]) as $g ({};
    .[$g[0].role].hosts = ([$g[] | del(.hostname, .role)[]] | unique)
)
'
{
  "db": {
    "hosts": [
      "172.17.0.5",
      "172.17.0.7",
      "172.17.0.8",
      "172.18.0.5"
    ]
  },
  "web": {
    "hosts": [
      "172.17.0.3",
      "172.17.0.4",
      "172.17.0.6"
    ]
  }
}

https://jqplay.org/s/ZGj1wC8hU3

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...