Конвертировать JSON в CSV / JQ не может перебрать строку - PullRequest
1 голос
/ 12 июля 2019
[
{
    "Description": "Copied for Destination xxx from Sourc 30c for Snapshot 1. Task created on X,52,87,14,76.",
    "Encrypted": false,
    "ID": "snap-074",
    "Progress": "100%",
    "Time": "2019-06-11T09:25:23.110Z",
    "Owner": "883065",
    "Status": "completed",
    "Volume": "vol1",
    "Size": 16
},
{
    "Description": "Copied for Destination yy from Source 31c for Snapshot 2. Task created on X,52,87,14,76.",
    "Encrypted": false,
    "ID": "snap-096",
    "Progress": "100%",
    "Time": "2019-06-11T10:18:01.410Z",
    "Owner": "1259",
    "Status": "completed",
    "Volume": "vol-2",
    "Size": 4
}

]

У меня есть тот json-файл, который я пытаюсь преобразовать в csv с помощью следующей команды:

     jq -r '. | map(.Description[], .Encrypted, .ID, .Progress, .Time, .Owner, .Status, .Volume, .Size | join(",")) | join("\n")' snapshots1.json

Но я получаю ошибку:

jq: error (at snapshots1.json:24): Cannot iterate over string ("Copied for...)

Я смотрю на аналогичный пост в jq: error: не могу перебрать строку , но не могу понять ошибку. Любая помощь приветствуется.

Ответы [ 3 ]

0 голосов
/ 12 июля 2019

Существует риск использования .. здесь для извлечения «значений» в объекте: что, если порядок ключей во входных объектах отличается между объектами?

Вот общий фильтр, который обращается к этомуи другие вопросы.Он также испускает подходящую строку заголовка:

def object2array(stream):
  foreach stream as $x (null;
    if . == null then $x | [true, keys_unsorted] else .[0]=false end;
    (if .[0] then .[1] else empty end),
    .[1] as $keys | $x | [getpath( $keys[] | [.]) ] );

Пример

def data: [{a:1,b:2}, {b:22,a:11,c:0}];

object2array(data[])

производит:

["a","b"]
[1,2]
[11,22]

Как раз для трубопровода до @csv или @tsv.

Решение

Таким образом, решение исходной проблемы по существу будет следующим:

object2array(.[]) | @csv
0 голосов
/ 12 июля 2019
jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' snapshots1.json >> myfile.csv

Нашел этот пост , который объясняет этот код, и он работал для меня.

0 голосов
/ 12 июля 2019

Я думаю, вы были на правильном пути. Вот как я это сделаю:

jq -r '.[] | map(..) | @csv' snapshot1.json > snapshot1.csv

Есть пара небольших проблем с вашим кодом:

  1. .Descriptions[] - Описания не имеют массива, поэтому квадратные скобки не работают - нет массива для открытия.
  2. Предположим, что мы избавляемся от квадратных скобок, вы видите, что код работает, поскольку он помещает содержимое объектов в массив. Однако он помещает содержимое в один массив - в результате ваш csv будет иметь только одну строку (и я предполагаю, что вы хотите, чтобы каждый объект находился в отдельных строках). Это связано с тем, что функция map помещает все содержимое в один массив (см. Документацию: jq Manual ) - поэтому сначала нужно разбить массив.
  3. Первая часть вашего кода с точкой (.) Ничего не делает - она ​​просто возвращает весь JSON как есть. Если вы хотите поиграть с ним, попробуйте .[], а затем поэкспериментируйте.

Отредактировано: орфография

...