将具有不可预测键值对的对象数组的 JSON 转换为 CSV
Convert JSON with array of objects of unpredictable key-value-pairs to CSV
我知道了 JSON:
[
{
"id": "1",
"tag": [
{
"k": "name",
"v": "Luxor"
}
]
},
{
"id": "2",
"tag": [
{
"k": "name",
"v": "Farflame"
},
{
"k": "magic",
"v": "30"
}
]
}
]
我想创建一个包含“id”、“name”和“magic”的 CSV。如果元素不存在,则应设置一个空字符串:
"id","name","magic"
"1","Luxor",""
"2","Farflame","30"
我快到了,但是如果不存在“magic”我就无法得到空字符串:
me@MBA test % jq -r '.[] | [.id, (.tag[] | select(.k=="name") | .v), (.tag[] | select(.k=="magic") | .v)] | @csv' simple.json
"1","Luxor"
"2","Farflame","30"
如您所见,id 为“1”的行只有两个单元格,因为“tag”中没有“magic”元素。我尝试了各种 if
语句,但没能找到一个符合我要求的语句。
动机
上面的玩具示例类似于 OpenStreetMap 导出的 OSM XML 代码。要将一些 OpenStreetMap 数据导入数据库,转换为表格结构是至关重要的一步。 OSM 将节点(或方式或关系)的所有标签存储在具有键“@k”和“@v”的对象数组中;您无法预测哪些键存在以及以什么顺序存在。
select
扩展性不佳。相反,我会编写一个类似于 from_entries
的函数,用于将 tag
数组转换为对象,并像这样使用它:
def f: map({(.k): .v}) | add;
.[] | [.id] + (.tag | f | [.name, .magic]) | @csv
我知道了 JSON:
[
{
"id": "1",
"tag": [
{
"k": "name",
"v": "Luxor"
}
]
},
{
"id": "2",
"tag": [
{
"k": "name",
"v": "Farflame"
},
{
"k": "magic",
"v": "30"
}
]
}
]
我想创建一个包含“id”、“name”和“magic”的 CSV。如果元素不存在,则应设置一个空字符串:
"id","name","magic"
"1","Luxor",""
"2","Farflame","30"
我快到了,但是如果不存在“magic”我就无法得到空字符串:
me@MBA test % jq -r '.[] | [.id, (.tag[] | select(.k=="name") | .v), (.tag[] | select(.k=="magic") | .v)] | @csv' simple.json
"1","Luxor"
"2","Farflame","30"
如您所见,id 为“1”的行只有两个单元格,因为“tag”中没有“magic”元素。我尝试了各种 if
语句,但没能找到一个符合我要求的语句。
动机
上面的玩具示例类似于 OpenStreetMap 导出的 OSM XML 代码。要将一些 OpenStreetMap 数据导入数据库,转换为表格结构是至关重要的一步。 OSM 将节点(或方式或关系)的所有标签存储在具有键“@k”和“@v”的对象数组中;您无法预测哪些键存在以及以什么顺序存在。
select
扩展性不佳。相反,我会编写一个类似于 from_entries
的函数,用于将 tag
数组转换为对象,并像这样使用它:
def f: map({(.k): .v}) | add;
.[] | [.id] + (.tag | f | [.name, .magic]) | @csv