我正在下载 api json 数据并将其转换为 csv 文件形式的最终结果。
样本数据的形式如下:
{
"content": [{
"Title": "abc",
"brand": "xyz",
"information": {
"c1": "101",
"c2": "11111",
"c3": "a,b,c,d,e:abc."
}
},
{
"Title": "RX100",
"brand": "Yamaha",
"information": {
"c1": "102",
"c2": "22222",
"c3": "a."
}
},
{
"Title": "victor",
"brand": "TVS",
"information": {
"c1": "103",
"c2": "33333",
"c3": "a,b,c"
}
},
{
"Title": "R15",
"brand": "Yamaha",
"information": {
"c1": "104",
"c2": "44444",
"c3": "a,b"
}
}
]
}
我已成功下载并根据标题数量转换为多个csv。转换为多个 csv 文件后,数据如下所示。
Headers-> c1,c2,c3
csv1--> 101,11111,a,b,c,d,e:abc.
csv2--> 102,22222,a.
csv3--> 103,33333,a,b,c.
csv4--> 104,44444,a,b.
但我想要以下形式的上述数据。
Headers-> c1,c2,c3,c4,c5,c6,c7
csv1--> 101,11111,a,b,c,d,e:abc.
csv2--> 102,22222,a.
csv3--> 103,33333,a,b,c.
csv4--> 104,44444,a,b.
是否可以使用 json.json. 根据我的 json 文件中存在的“,”将 c3 划分为不同数量的列。 c3 列将根据存在的元素数量进行划分,并且将是 c3 数据的最大值。
答案1
对于这个准确的数据,
jq -r '.content[].information | [.c1, .c2, .c3] | join(",")' < sample.json
会起作用 - 只需在三列之间插入逗号即可复制连接的 CSV 文件的效果。对于更复杂的实际数据,特别是数字,这会更好:
jq -r '.content[].information | [.c1, .c2, (.c3|split(",")|.[])] | @csv' < sample.json
这一切都相当标准.c3|split(",")|.[]
,其中
- 提取第 3 列的值
- 将该值拆分为逗号数组
- 展平该数组
@csv
然后将数组转换为 CSV 格式。这将为您的示例文件生成以下输出:
"101","11111","a","b","c","d","e:abc."
"102","22222","a."
"103","33333","a","b","c"
"104","44444","a","b"
如果您不需要引号,最可靠的方法是使用@tsv
并替换选项卡:
jq -r '.content[].information|[.c1, .c2, .c3|split(",")|.[]] | @tsv|gsub("\t"; ",")' < sample.json
如果您的所有值都是字符串,您也可以join(",")
再次使用。
如果您还想创建文字标题行c1,...c7
,可以这样做:
jq -r '[.content[].information|[.c1, .c2, (.c3|split(",")|.[])]] | (([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(",")), (.[] | join(",")))' < sample.json
共有三个部分:第一个部分像以前一样创建列数组,然后其他两个部分将其用作输入:
([range([.[] | length] | max)|"c" + (.+1|tostring)]|join(","))
生成标题行:它通过生成行长度数组来查找任何行的最大长度,创建范围 0..maximum 并映射它以创建“c1”..“c7”数组,然后将它们全部连接起来与逗号一起。(.[] | join(","))
与之前的后半部分类似,同样的事情也@csv
适用。