jq: сгенерировать JSON: возможно создание динамического ключа?

Я никогда не использовал jq для генерации JSON, только для анализа. Так что это неизведанная территория для меня.

Я нашел jq & bash: создать массив JSON из переменной, который получает меня ближе к тому, что я ищу. Однако мне еще предстоит определить, как динамически создавать имена ключей для структуры, которую я ищу.

Структура, которую я ищу, выглядит примерно так:

{
  "eth0":
        {
            "key1": "value1",
            "key2": "value2",
            "key3": "value3"
        },
  "eth3":
        {
            "key1": "value1",
            "key2": "value2",
            "key3": "value3"
        }
}

получено из CSV:

iface,key1,key2,key3
eth0,value1,value2,value3
eth3,value1,value2,value3

У меня возникла проблема с динамической генерацией ключей в JSON из CSV. Я не смог найти способность jq сделать это. Я использую JQ 1.5.

Я прокручиваю свои колеса на этом?

ИЗМЕНИТЬ — возможный ответ

В настоящее время изучает этот ответ поваренной книги:

https://github.com/stedolan/jq/wiki/Cookbook#convert-a-csv-file-with-headers-to-json


person Jim    schedule 12.02.2016    source источник


Ответы (2)


В идеале ваш ввод должен быть JSON, поэтому вы должны запустить свой файл через что-то, что может преобразовать ваш CSV-файл в массивы, содержащие ваши данные, чтобы он мог использоваться jq. Предполагая, что ваши данные не будут сложными, а сами значения не будут содержать запятых, вы можете прочитать необработанные строки и разделить их. Тогда это просто вопрос создания вашего результата.

$ jq -R 'split(",") as $k |
    reduce (inputs | split(",")) as $r ({};
        .[$r[0]] = ([range(1;$k|length) | { key: $k[.], value: $r[.] }] | from_entries)
    )' input.csv
person Jeff Mercado    schedule 13.02.2016
comment
Учитывая, что мои данные очень просты, я отметил это как ответ. Он работает отлично, хотя мне нужно было немного изменить свой csv, но это было на мне. Очень ценю этот ответ. Другой возможный ответ (в моем редактировании) также находится в правильном направлении, однако я использую этот, поскольку он более лаконичен и работает для моего варианта использования. - person Jim; 13.02.2016

Вот простое решение, которое на самом деле очень похоже на решение Джеффа (в частности, оно делает те же предположения о CSV), но использует input для первой строки, inputs для остальных строк, упрощенную версию «объективировать» из jq Cookbook и add вместо reduce в основном фильтре:

jq -R -n '
  def objectify(headers): . as $in
    | reduce range(0; headers|length) as $i
        ({}; .[headers[$i]] = $in[$i]  );

  ((input|split(","))[1:]) as $headers
  | [ (inputs|split(",")) as $line
      | { ($line[0]): ($line[1:] | objectify($headers)) } ]
  | add
'
person peak    schedule 13.02.2016