使用jq从json创建CSV,基于数组中的元素

时间:2017-01-12 05:22:01

标签: json csv jq

我有以下需要转换为CSV的json格式

[{
            "name": "joe",
            "age": 21,
            "skills": [{
                "lang": "spanish",
                "grade": "47",
                "school": {
                    "name": "my school",
                    "url": "example.com/sp-school"
                }
            }, {
                "lang": "english",
                "grade": "87"
            }]

        },

        {
            "name": "sarah",
            "age": 34,
            "skills": [{
                "lang": "french",
                "grade": "47",
                "school": {
                    "name": "my school",
                    "url": "example.com/sp-school"
                }
            }, {
                "lang": "english",
                "grade": "87"
            }]

        }, {
            "name": "jim",
            "age": 26,
            "skills": [{
                "lang": "spanish",
                "grade": "60"

            }, {
                "lang": "english",
                "grade": "66",
                "school": {
                    "name": "eg school",
                    "url": "eg-school.com"

                }
            }]

        }
    ]

转换为csv

name,age,grade,school,url,file,line_number
joe,21,47,"my school","example.com/sp-school",sample.json,1
jim,26,60,"","",sample.json,3

如果lang = spanish,则从技能数组中添加顶级字段和对象,如果存在,则从西班牙语的技能对象添加学校哈希

我还想添加它来自的文件和行号。

我想用jq来完成这项工作,但是无法弄清楚语法,有谁帮帮我?

1 个答案:

答案 0 :(得分:1)

使用input.json中的数据和tocsv.jq中的以下jq程序:

.[]
| [.name, .age] +
  (.skills[]
  | select(.lang == "spanish")
  | [.grade, .school.name, .school.url, input_filename, input_line_number] )
| @csv

调用:

jq -r -f tocsv.jq  input.json

的产率:

"joe",21,"47","my school","example.com/sp-school","input.json",51
"jim",26,"60",,,"input.json",51

如果您希望将数值字符串转换为数字,则可以使用“tonumber”过滤器。如果您希望将空值字段替换为字符串,请使用例如.school.name // ""

当然,这种方法不会产生非常有用的行号。一种可以产生更高粒度的方法是将单个对象流式传输到jq中,但之后就会丢失文件名。要恢复文件名,您可以将其作为参数传递。所以你会有这样的管道:

jq -c '.[]' input.json | jq -r --arg file input.json -f tocsv2.jq

其中tocsv2.jq与上面的tscsv.jq类似,但没有初始.[] |,而$file代替input_filename

最后,还请考虑使用TSV格式(@tsv)而不是相当混乱的CSV格式(@csv)。