Вот решение, которое обрабатывает массивы во входном JSON путем преобразования их в «значения, разделенные двоеточиями»:
def atos: map(tostring) | join(":");
Используются те же общие allpaths
фильтры, что и в других местах на этой странице:
# Generate a stream of all paths, including paths to null
def allpaths:
def conditional_recurse(f): def r: ., (select(.!=null) | f | r); r;
path(conditional_recurse(.[]?)) | select(length > 0);
def allpaths(filter):
allpaths as $p | getpath($p) as $v | select($v | filter) | $p;
Опять же для случая одного объекта решение может быть получено следующим образом:
walk( if type == "array" then atos else . end )
| [allpaths(scalars)] as $p
| ($p | map(last) | @csv),
([getpath($p[])] | @csv)
выход
Для данного ввода, вывод будет:
"company_number","address_line_1","country","locality","postal_code","premises","region","country_of_residence","month","year","etag","kind","self","name","forename","middle_name","surname","title","nationality","natures_of_control","notified_on"
"09626947","Troak Close","England","Christchurch","BH23 3SR","9","Dorset","United Kingdom",11,1979,"7123fb76e4ad7ee7542da210a368baa4c89d5a06","individual-person-with-significant-control","/company/09626947/persons-with-significant-control/individual/FFeqke7T3LvGvX6xmuGqi5SJXAk","Ms Angela Lynette Miller","Angela","Lynette","Miller","Ms","British","significant-influence-or-control","2016-06-06"
Протест
Представленное здесь решение предназначено только для использования, когда все массивы на входе имеют скалярное значение.
Эффективная обработка потока изоморфных объектов
Далее предполагается, что поток объектов изоморфен в том смысле, что упорядочение ключей внутри объекта JSON не имеет значения.
Инфраструктура
Инфраструктура allpaths
и atos
такая же, как и выше, поэтому здесь повторяться не будет.
Вспомогательные функции
# input: an object
def paths:
walk( if type == "array" then atos else . end )
| [allpaths(scalars)] ;
# input: an array of paths
def headers:
map(last) | @csv ;
# input: an object
def row($paths):
walk( if type == "array" then atos else . end )
| [getpath($paths[])]
| @csv ;
Обработка входного потока
Следующее использует input
для чтения первого объекта и inputs
для чтения остальных, поэтому важно вызывать jq с параметром командной строки -n:
input as $first
| ($first|paths) as $paths
| ($paths | headers),
($first | row($paths)),
(inputs | row($paths))