我有以下 JSON 文件:
{ data : [
{
"name" : "name1"
"date" : [
{
"date1" : "aaa",
"date2" : "bbb"
},
{
"date1" : "ccc",
"date2" : "ddd"
},
{
"date1" : "eee",
"date2" : "fff"
},
"var" : "ggg"
},
{
"name" : "name2"
"date" : [
{
"date1" : "hhh",
"date2" : "iii"
},
{
"date1" : "jjj",
"date2" : "kkk"
},
"var" : "lll"
}
]
}
我想要以下格式的 CSV 文件:
name, date, var
name1, aaa ccc eee, ggg
name2, hhh jjj, lll
仅使用 jq 可以吗?
答案1
假设您的 JSON 文档格式良好,如您所呈现的文本的以下修改后的变体:
{
"data": [
{
"name": "name1",
"date": [
{
"date1": "aaa",
"date2": "bbb"
},
{
"date1": "ccc",
"date2": "ddd"
},
{
"date1": "eee",
"date2": "fff"
}
],
"var": "ggg"
},
{
"name": "name2",
"date": [
{
"date1": "hhh",
"date2": "iii"
},
{
"date1": "jjj",
"date2": "kkk"
}
],
"var": "lll"
}
]
}
然后我们可以执行以下操作:
$ jq -r '[ "name", "date", "var" ], (.data[] | [.name, ([.date[].date1] | join(" ")), .var]) | @csv' file
"name","date","var"
"name1","aaa ccc eee","ggg"
"name2","hhh jjj","lll"
这个jq
表达式,用更多的空气来显示结构:
[ "name", "date", "var" ],
(
.data[] |
[
.name,
( [ .date[].date1 ] | join(" ") ),
.var
]
) |
@csv
这首先将 CSV 标头创建为字符串数组。然后它迭代顶级数组,将和键data
的值拉出到数组中。它还挑选出数组中子键的所有值,并将它们与空格作为分隔符连接起来。name
var
date1
date
data
然后,使用 处理CSV 标头数组以及为每个元素构建的数组以进行输出@csv
,该数组引用每个字符串并用逗号分隔元素。
另一种变体:
box% jq -r '.data[].date |= ( [.[].date1] | join(" ") ) | [ (.data[0] | keys[]) ], (.data[]| [.[]]) | @csv' file
"date","name","var"
"name1","aaa ccc eee","ggg"
"name2","hhh jjj","lll"
这会对数据进行预处理,以便第一个管道之后的表达式部分获得以下输入:
{
"data": [
{
"name": "name1",
"date": "aaa ccc eee",
"var": "ggg"
},
{
"name": "name2",
"date": "hhh jjj",
"var": "lll"
}
]
}
第一个管道之后的代码只需提取 CSV 标头的键,然后收集值,而不必担心键的名称。
再次,jq
为了说明目的,插入了一点空气的表达式:
.data[].date |= ( [ .[].date1 ] | join(" ") ) |
[ (.data[0] | keys[]) ],
( .data[] | [.[]] ) |
@csv
看起来很时髦,.data[] | [.[]]
它创建了一个包含 的每个元素中所有键的值的数组data
。
如果担心.[]
应用于非数组可能会以与keys
生成的顺序不同的顺序提取值,那么可以使用
.data[].date |= ( [ .[].date1 ] | join(" ")) |
(.data[0] | keys) as $keys |
$keys,
( .data[]| [ .[$keys[]] ] ) |
@csv
即,将标题键拉出到变量中$keys
,使用它来创建 CSV 标头和用于从数组中的元素中提取数据data
。这些列可能采用随机顺序,但至少标题和其余数据采用相同的随机顺序,并且 CSV 解析器按名称提取列不会有任何问题。