JSON - > CSV создание строки заголовка и заполнения заголовка, если найдено пустое поле

java.lang.SecurityException: Prohibited package name: java

Вы не можете использовать java в качестве имени вашего пакета. Замените его на что-то еще.

0
задан Tytire Recubans 18 March 2019 в 16:47
поделиться

2 ответа

Вот подход, основанный на программном определении заголовков. Чтобы проиллюстрировать это, мы ограничиваем внимание одним объектом.

Поскольку встроенная функция jq paths игнорирует пути к нулю, и поскольку одно из требований здесь - НЕ игнорировать такие пути, мы начнем с определения некоторых фильтров, аналогичных paths/0 и paths/1:

[ 110]

Далее мы определим функцию для сокращения длинных путей. Вы можете приспособить это к вашим потребностям.

# 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"
0
ответ дан peak 18 March 2019 в 16:47
поделиться

Вот решение, которое обрабатывает массивы во входном 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"

Caveat

Представленное здесь решение предназначено только для использования, когда все массивы на входе имеют скалярное значение.

Эффективная обработка потока изоморфных объектов

Далее предполагается, что поток объектов изоморфен в том смысле, что упорядочение ключей внутри объекта 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))
0
ответ дан peak 18 March 2019 в 16:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: