Как преобразовать json с массивом в csv?

Я знаю, что это возможно с jq, но есть дополнительная сложность. Одно из полей внутри объекта json - это массив строк. Как мы справимся с этим с помощью jq?

{
    "var": 1,
    "section": ["1","2","3"],
    "x": "test1"
},
{
    "var": 2,
    "section": ["2","3","4"],
    "x": "test2"
},
{
    "var": 3,
    "section": ["3","4","5"],
    "x": "test3"
},

Как сделать такой вывод CSV?

var,section,x
"1","[1,2,3]","test1"
"2","[2,3,4]","test2"
"3","[3,4,5]","test3"

Я собираюсь использовать JSON.stringify внутри аргументов jq.


person WantIt    schedule 08.01.2017    source источник


Ответы (1)


С предостережением, что вы должны быть осторожны с тем, чего хотите, и предполагая, что ввод представляет собой массив объектов, как показано:

.[]
| [.[]
   | if type == "array" then map(tonumber? // .) else . end
   | tostring]
| @csv

производит желаемый результат, за исключением строки заголовка.

(«Число? //.» Позволяет избежать ошибки, если содержимое массива не может быть преобразовано в число.)

Обобщение

Вот вариант, который (а) создает строку заголовков для всех ключей в первом объекте, какими бы они ни были; и (b) надежен в отношении переупорядочения ключей в объектах:

. as $in | ($in[0] | keys_unsorted) as $h | ($h, ( $in[] | ( [range(0; $h|length) as $i | getpath( [$h[$i]] )] | map(if type == "array" then map(tonumber? // .) else . end) | map(tostring) ) )) | @csv

С помощью этого в tocsv.jq и вашего ввода в input.json:

$ jq -r -f tocsv.jq input.json "var","section","x" "1","[""a"",2,3]","test1" "2","[2,3,4]","test2" "3","[3,4,5]","test3"

person peak    schedule 08.01.2017