Jq: печатать ключ и значение для каждой записи в объекте

Как мне получить jq, чтобы взять json вот так:

{
  "host1": { "ip": "10.1.2.3" },
  "host2": { "ip": "10.1.2.2" },
  "host3": { "ip": "10.1.18.1" }
}

и сгенерируйте этот вывод:

host1, 10.1.2.3
host2, 10.1.2.2
host3, 10.1.18.1

Мне не интересно форматирование, я просто не могу понять, как получить доступ к имени и значению ключа.

Ответы

Ответ 1

Чтобы получить ключи верхнего уровня в виде потока, вы можете использовать клавиши []. Таким образом, одним из решений вашей конкретной проблемы было бы следующее:

jq -r 'keys[] as $k | "\($k), \(.[$k] | .ip)"' 

keys создает имена ключей в отсортированном порядке; если вы хотите их в исходном порядке, используйте keys_unsorted.

Другая альтернатива, которая производит ключи в исходном порядке:

jq -r 'to_entries[] | "\(.key), \(.value | .ip)"'

Выход CSV и TSV

Фильтры @csv и @tsv также могут быть рассмотрены здесь, например.

jq -r 'to_entries[] | [.key, .value.ip] | @tsv'

дает:

host1   10.1.2.3
host2   10.1.2.2
host3   10.1.18.1

Ответ 2

Наткнулся на очень элегантное решение

jq 'with_entries(.value |= .ip)'

Какие выходы

{
  "host1": "10.1.2.3",
  "host2": "10.1.2.2",
  "host3": "10.1.18.1"
}

Вот фрагмент кода jqplay для игры: https://jqplay.org/s/Jb_fnBveMQ

Функция with_entries преобразует каждый объект в списке объектов в пару ключ/значение, поэтому мы можем получить доступ к .key или .value соответственно, мы обновляем (перезаписываем) каждый элемент KV .value полем .ip с помощью оператора update |=