Подсчет сгруппированных членов массива JSON с помощью jq 1.3 со встроенным выводом - PullRequest
3 голосов
/ 03 апреля 2019

У меня есть файл JSON:

[
  {
    "instance_AZs": [
        "us-east-1b",
        "us-east-1b",
        "us-east-1b",
        "us-east-1c",
        "us-east-1c",
        "us-east-1a",
        "us-east-1a",
        "us-east-1c",
        "us-east-1b",
        "us-east-1a",
        "us-east-1a",
        "us-east-1c",
        "us-east-1a",
        "us-east-1b",
        "us-east-1b",
        "us-east-1c",
        "us-east-1c",
        "us-east-1b"
    ],
    "ASGname": "myapp"
  }
]

Желаемый вывод:

myapp.us-east-1a.5
myapp.us-east-1b.7
myapp.us-east-1c.6

Насколько я могу использовать синтаксис jq 1.3, я написал такой код:

cat file.json | jq -r '.[] | .ASGname, (.instance_AZs | group_by(.) | map(. | length , (. | unique ) [] ))'

которые выдают результат:

myapp
[
  5,
  "us-east-1a",
  7,
  "us-east-1b",
  6,
  "us-east-1c"
]

Подскажите, пожалуйста, как генерировать желаемый результат?

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019
.[]
| .ASGname as $p
| reduce .instance_AZs[] as $k ({}; .[$k]+=1)
| keys_unsorted[] as $k
| "\($p).\($k).\(.[$k])"

приведите instance_AZs к объекту, где уникальные элементы массива являются ключами к их счетчикам повторений в массиве, используйте его для получения желаемого результата.

или, если вы настаиваете на этом по-своему, объединяет группы в интерполированную строку вместо map, т.е. ссылается на ответ @ hek2mgl.

2 голосов
/ 03 апреля 2019

Это способ сделать это:

jq -r '.[]|.ASGname as $g|.instance_AZs|group_by(.)[]|"\($g).\(.[0]).\(length)"' file.json
...