我有很多相当大的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
答案 0 :(得分:1)
您需要运行两次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拆分为多个文件,嵌入式原始换行都存在潜在问题。一种方法是将JSON字符串中的“\ n”更改为“\\ n”,例如
jq -r '([.id,.type],[.id,.group])
| map(if type == "string" then gsub("\n";"\\n") else . end)
| @csv'
答案 1 :(得分:1)
我认为你可以解决这个问题的一种方法是将一个文件的内容输出到stdout,将其他文件的内容输出到stderr并重定向到单独的文件。当然,你只限于两个文件。
$ <testJQ.log jq -r '([.id,.type]|@csv),([.id,.group]|@csv|stderr|empty)' \
1>types.csv 2>groups.csv
stderr
输出到stderr,但值传播到输出,因此您需要使用empty
跟随它以吞下它。
我个人不建议这样做,如果你需要输出到多个文件,我会写一个python脚本(或其他语言)来解析它。