如何在json中拆分字符串值并使用jq转换为嵌套对象?

时间:2018-10-04 11:50:50

标签: json openstreetmap geojson jq

我正在尝试使用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指令,同时还能如上所述获得所需的输出?

3 个答案:

答案 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),但是我一直保持简单,因此您可以轻松进行修改以满足更详细的要求。