java.lang.SecurityException: Prohibited package name: java
Вы не можете использовать java в качестве имени вашего пакета. Замените его на что-то еще.
Вот подход, основанный на программном определении заголовков. Чтобы проиллюстрировать это, мы ограничиваем внимание одним объектом.
Поскольку встроенная функция jq paths
игнорирует пути к нулю, и поскольку одно из требований здесь - НЕ игнорировать такие пути, мы начнем с определения некоторых фильтров, аналогичных paths/0
и paths/1
:
Далее мы определим функцию для сокращения длинных путей. Вы можете приспособить это к вашим потребностям.
# Input: an array denoting a path; output: a string
def abbreviate: if .[-1]|type == "number" then "\(.[-2]):\(.[-1])" else "\(.[-1])" end;
Наконец, мы собираем все вместе для случая одного объекта, генерируя строку заголовков, за которой следует строка соответствующих значений:
[allpaths(scalars)] as $p
| ($p | map(abbreviate) | @csv),
([getpath($p[])] | @csv)
Для объекта JSON, о котором идет речь, выходные данные, полученные с помощью описанного выше (с использованием параметра командной строки -r), будут следующими 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:0","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 путем преобразования их в «значения, разделенные двоеточиями»:
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)
Для данного входа, выход будет be:
"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))