Это очень близко к запрошенному выводу.
jq -c 'to_entries[]
| if .value|type == "object"
then .key as $k
| .value
| to_entries[]
| ["\($k).\(.key)", (.value|type)]
else [.key, (.value|type)]
end'
Вывод:
["parameter.colA","string"]
["parameter.COLB","string"]
["workRequired","number"]
["work","number"]
["updateType","string"]
Основное различие заключается в первых двух строках. Я не думаю, что ["parameter"."colA","string']
является действительным JSON.
Некоторые типы также отличаются.
Пояснение
Один из способовизучение того, как это работает, должно идти шаг за шагом. Поэтому начните с jq -c 'to_entries[]'
, чтобы увидеть, что получится, а затем добавляйте каждый шаг по очереди. Руководство также довольно хорошо.
Здесь мы начнем с объекта. Первая команда - to_entries[]
. Цитируя руководство, когда «to_entries передается объект, то для каждой записи k: v во входном файле выходной массив включает в себя {« key »: k,« value »: v}». Добавление []
в конце означает, что на выходе будут только объекты в массиве, которые создает to_entries
. Итак, это вывод после первого шага:
{"key":"parameter","value":{"colA":"No","COLB":"No"}}
{"key":"workRequired","value":0}
{"key":"work","value":0}
{"key":"updateType","value":"AUTO"}
Теперь у нас есть четыре объекта. Один содержит другой объект. Первоначальный вопрос касается объекта, который содержит объект. Проблема заключалась в том, чтобы объединить ключ для содержащего объекта с ключом для содержащегося объекта в конечном выводе.
Условное if .value|type == "object"
идентифицирует объект, содержащий объект.
Когда этоЕсли условие выполнено, .key as $k
сохраняет значение ключа «key» объекта-объекта как переменную с именем $ k.
Затем мы повторяем to_entries[]
с содержащимся объектом. Содержащийся объект - это значение ключа «значение» в содержащем объекте. Код .value | to_entries[]
фильтрует содержащийся объект через to_entries[]
. Это дает нам эти два объекта.
{"key":"colA","value":"No"}
{"key":"COLB","value":"No"}
Чтобы создать желаемый результат, нам нужно создать массив, который объединяет ключ содержащего объекта, который был сохранен как $ k, с элементами этих двухобъекты. Вот как мы это делаем. (См. «Интерполяция строк» в руководстве для объяснения того, как работает часть в кавычках.)
["\($k).\(.key)", (.value|type)]
Для каждого объекта ключ, который мы сохранили как переменную $ k, имеет видв сочетании со значением ключа «ключ» в объекте. Затем мы выводим тип значения ключа «значение» в объекте.
Это дает первые две строки окончательного результата:
["parameter.colA","string"]
["parameter.COLB","string"]
Теперь мы переходим к другомуветка наша условная. Это касается трех объектов первого этапа, которые не содержат объектов. Здесь мы просто повторяем исходный код вопроса, поскольку он был удовлетворительным.
else [.key, (.value|type)]
Это дает следующее:
["workRequired","number"]
["work","number"]
["updateType","string"]
Команда end
завершает условное выражение.
Еще одна вещь. Флаг -c
в самом начале говорит jq, что мы хотим компактный вывод. Без него выходные данные были бы логически одинаковыми, но распределенными по нескольким строкам.