Как создать 2 файла CSV из 1 JSON, используя JQ - PullRequest
0 голосов
/ 24 мая 2018

У меня много довольно больших журналов JSON, которые нужно импортировать в несколько таблиц БД.Я могу легко разобрать их и создать 1 CSV для импорта.Но как я могу проанализировать JSON и получить 2 разных файла CSV в качестве вывода?Простой (бессмысленный) пример:

testJQ.log

{"id":1234,"type":"A","group":"games"}
{"id":5678,"type":"B","group":"cars"}

с использованием

cat testJQ.log|jq --raw-output '[.id,.type,.group]|@csv'>testJQ.csv

Я получаю один файл testJQ.csv

1234,"A","games
5678,"B","cars"

Но я хотел бы получить это

types.csv

1234,"A"
5678,"B"

groups.csv

1234,"games"
5678,"cars"

Можно ли это сделать, не разбирая JSON дважды, сначалавремя создания types.csv и второй раз groups.csv, как это?

cat testJQ.log|jq --raw-output '[.id,.type]|@csv'>types.csv
cat testJQ.log|jq --raw-output '[.id,.group]|@csv'>groups.csv

Ответы [ 2 ]

0 голосов
/ 24 мая 2018

Полагаю, вы могли бы взломать это одним способом - вывести содержимое одного файла в stdout, а остальные - в stderr и перенаправить в отдельные файлы.Конечно, вы ограничены двумя файлами.

$ <testJQ.log jq -r '([.id,.type]|@csv),([.id,.group]|@csv|stderr|empty)' \
    1>types.csv 2>groups.csv

stderr выводит в stderr, но значение распространяется на вывод, так что вы захотите дополнить это empty, чтобы проглотить этоup.

Лично я бы не рекомендовал делать это, я просто написал бы скрипт на python (или другой язык), чтобы проанализировать это, если вам нужно вывести на несколько файлов.

0 голосов
/ 24 мая 2018

Вам нужно будет либо запустить jq дважды, либо запустить jq совместно с другой программой, чтобы «разделить» вывод вызова jq.Например, вы можете использовать конвейер в форме: jq -c ... | awk ...

Потенциальный недостаток конвейерного подхода состоит в том, что если JSON является конечным выходом, это будет JSONL;но очевидно, что здесь это не относится.

Есть много способов создать такой трубопровод.Например, при условии, что в CSV нет необработанных строк новой строки:

< testJQ.log jq -r '
    "types",  ([.id,.type] |@csv),
    "groups", ([.id,.group]|@csv)' |
  awk 'NR % 2 == 1 {out=$1; next} {print >> out".csv"}'

Или:

< testJQ.log jq -r '([.id,.type],[.id,.group])|@csv' |
    awk '{ out = ((NR % 2) == 1) ? "types" : "groups"; print >> out".csv"}'

Другие примеры см., Например,

Обработка необработанных новых строк

Независимо от того, разделяете ли вы CSV на несколько файлов, существует потенциальная проблема со встроенными необработанными символами новой строки.Один из подходов заключается в том, чтобы изменить "\ n" в строках JSON на "\\ n", например

jq -r '([.id,.type],[.id,.group])
       | map(if type == "string" then gsub("\n";"\\n") else . end)
       | @csv'
...