我正在尝试使用jq转换如下内容:
[
{
"type": "Feature",
"properties": {
"osm_id": "172544",
"highway": "crossing",
"other_tags": "\"crossing\"=>\"uncontrolled\",\"tactile_paving\"=>\"yes\""
},
"geometry": {
"type": "Point",
"coordinates": [
13.3432342,
52.5666157
]
}
}
]
对此:
[
{
"type": "Feature",
"properties": {
"osm_id": "172544",
"highway": "crossing",
"other_tags": {
"crossing": "uncontrolled",
"tactile_paving": "yes"
}
},
"geometry": {
"type": "Point",
"coordinates": [
13.3432342,
52.5666157
]
}
}
]
现在,这是我的进度:
jq 'map(try(.properties.other_tags |= split(",") // .)) | map(try(.properties.other_tags[] |= split("=>") // .)) | map(try(.properties.other_tags[] |= { (.[0]) : .[1] } // .))' example.json
但是“ other_tags”的输出看起来像这样:
"other_tags": [
{
"\"crossing\"": "\"uncontrolled\""
},
{
"\"tactile_paving\"": "\"yes\""
}
]
我很确定这不如预期的好。
它用于转换相当大的osm导出
我是否可以使用更优雅/更简短的jq指令,同时还能如上所述获得所需的输出?
答案 0 :(得分:2)
您还可以使用此:
<file jq '[.[] | try(.properties.other_tags |= ("{" + gsub("=>"; ":") + "}" | fromjson))//.]'
这会在所需的字符串中添加大括号{
和}
并将=>
替换为:
。然后使用命令fromjson
将字符串转换为JSON对象。
如果未找到.properties.other_tags
,则该命令不会更改JSON数据。
答案 1 :(得分:0)
在摆弄jqplay的同时找到了令人满意的解决方案:
jq '.features
| map(try(.properties.other_tags |=
(split("\",\"")
| join("\"##strsplit##\"")
| split("##strsplit##")
| .[] |= split("=>")
| .[] |= {(.[0][1:-1]): (.[1][1:-1])}
| add)) // .)'
编辑:更改了数组索引,这要感谢peak的评论
edit2:逗号允许,并且包含不带“ other_tags”的节点
答案 2 :(得分:0)
这是一个解决方案,假定可以将输入解析为与以下正则表达式(表示为JSON)匹配的逗号分隔的段:
"\"(?<key>[^\"]+)\"=>\"(?<value>[^\"]+)\""
# emit a stream
def unwrap:
. as $s
| if length==0 then empty
else match( "\"(?<key>[^\"]+)\"=>\"(?<value>[^\"]+)\",?" )
| (.captures|map({(.name): .string})|add),
( $s[.length:]|unwrap)
end
;
map( .properties.other_tags |= ([unwrap]|from_entries) )
此方法具有(潜在的)优点,即允许在键和值内出现逗号和“ =>”。当然,可以使实现更加稳定(例如,像您一样使用try
),但是我一直保持简单,因此您可以轻松进行修改以满足更详细的要求。