如何解析 ovs-vsctl 的结果获取接口 <interface> 统计信息

结果示例:

{collisions=0, rx_bytes=258, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=3, tx_bytes=648, tx_dropped=0, tx_errors=0, tx_packets=8}

这种格式类似于 JSON,但不是 JSON。

有没有一种简单的方法可以将其解析为map[string]int?喜欢json.Unmarshal(data, &value)


忽然笑
浏览 328回答 2
2回答

红糖糍粑

如果该传输格式不是递归定义的,即一个键不能启动一个子结构,那么它的语言是常规的。因此,您可以使用 Go 的标准regexp包来解析它:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "regexp"&nbsp; &nbsp; "strconv")const data = `{collisions=0, rx_bytes=258, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=3, tx_bytes=648, tx_dropped=0, tx_errors=0, tx_packets=8}`const regex = `([a-z_]+)=([0-9]+)`func main() {&nbsp; &nbsp; ms := regexp.MustCompile(regex).FindAllStringSubmatch(data, -1)&nbsp; &nbsp; vs := make(map[string]int)&nbsp; &nbsp; for _, m := range ms {&nbsp; &nbsp; &nbsp; &nbsp; v, _ := strconv.Atoi(m[2])&nbsp; &nbsp; &nbsp; &nbsp; vs[m[1]] = v&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("%#v\n", vs)}

慕后森

您可以通过使用strings.Split()以逗号空格 ( ", ")分割以获得对,然后再次使用等号 ( "=")分割以获得键值对来获得更有效的解决方案。之后,您只需要将这些放入地图中:func Parse(s string) (m map[string]int, err error) {&nbsp; &nbsp; if len(s) < 2 || s[0] != '{' || s[len(s)-1] != '}' {&nbsp; &nbsp; &nbsp; &nbsp; return nil, fmt.Errorf("Invalid input, no wrapping brackets!")&nbsp; &nbsp; }&nbsp; &nbsp; m = make(map[string]int)&nbsp; &nbsp; for _, v := range strings.Split(s[1:len(s)-1], ", ") {&nbsp; &nbsp; &nbsp; &nbsp; parts := strings.Split(v, "=")&nbsp; &nbsp; &nbsp; &nbsp; if len(parts) != 2 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil, fmt.Errorf("Equal sign not found in: %s", v)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if m[parts[0]], err = strconv.Atoi(parts[1]); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil, err&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return}使用它:s := "{collisions=0, rx_bytes=258, ...}"fmt.Println(Parse(s))在Go Playground.注意:如果性能很重要,可以通过不strings.Split()在外循环中使用,而是“手动”搜索逗号并维护索引,并且仅“取出”代表实际键和值的子字符串来改进这一点(但此解决方案将更复杂)。另一个解决方案......但此选项要慢得多,因此只有在性能不是关键要求时才可行:您可以将输入字符串转换为有效的 JSON 格式,然后您可以使用json.Unmarshal(). 省略了错误检查:s := "{collisions=0, rx_bytes=258, ...}"// Turn into valid JSON:s = strings.Replace(s, `=`, `":`, -1)s = strings.Replace(s, `, `, `, "`, -1)s = strings.Replace(s, `{`, `{"`, -1)// And now simply unmarshal:m := make(map[string]int)json.Unmarshal([]byte(s), &m)fmt.Println(m)此解决方案的优点是,如果您解组的目标值是 a ,这也有效struct:// Unmarshal into a struct (you don't have to care about all fields)st := struct {&nbsp; &nbsp; Collisions int `json:"collisions"`&nbsp; &nbsp; Rx_bytes&nbsp; &nbsp;int `json:"rx_bytes"`}{}json.Unmarshal([]byte(s), &st)fmt.Printf("%+v\n", st)在Go Playground.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go