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 |=