go - 如何从 map 界面解析特定键?

标签 go yaml

我正在读取一个 yaml 文件,并将其解码为一个 map[interface{}]interface{}。目标是替换 yaml 中的某个值,并用替换的值更新读入的文件。我不确定如何解析 map 以获取我想要更改的特定 key (password)。我相信你可以使用 reflect,但我不是 100% 确定语法

我正在阅读的 YAML 文件 (config.yml):

i_name: example

instances:
  - name: test-instance
    command: get
    arguments:
        hostname: localhost
        port: 203
        username: test
        password: testing123
    labels:
        env: dev

到目前为止的代码:

func replaceConfigPassword() {
    yamlFile, err := ioutil.ReadFile("config.yml")
    fatalIfErr(err)

    m := make(map[interface{}]interface{})

    err = yaml.Unmarshal(yamlFile, &m)
    fatalIfErr(err)

    fmt.Println(m)

    val := reflect.ValueOf(m["instances"]["arguments"]["password"])
    fmt.Println("val=", val)

最佳答案

下面显示了如何逐步执行 yaml 以获取密码:

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
)

func main() {
    in := []byte(`
i_name: example

instances:
  - name: test-instance
    command: get
    arguments:
        hostname: localhost
        port: 203
        username: test
        password: testing123
    labels:
        env: dev
`)

    m := make(map[string]interface{})
    if err := yaml.Unmarshal(in, &m); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", m)

    instances := m["instances"].([]interface{})
    fmt.Printf("%+v\n", instances)

    first := instances[0]
    fmt.Printf("%+v\n", first)

    arguments := first.(map[interface{}]interface{})["arguments"]
    fmt.Printf("%+v\n", arguments)

    password := arguments.(map[interface{}]interface{})["password"]
    fmt.Printf("%+v\n", password)
}
$ go run main.go
map[i_name:example instances:[map[name:test-instance command:get arguments:map[password:testing123 hostname:localhost port:203 username:test] labels:map[env:dev]]]]
[map[name:test-instance command:get arguments:map[hostname:localhost port:203 username:test password:testing123] labels:map[env:dev]]]
map[name:test-instance command:get arguments:map[hostname:localhost port:203 username:test password:testing123] labels:map[env:dev]]
map[username:test password:testing123 hostname:localhost port:203]
testing123

如果您事先知道输入结构,另一种选择是对其进行显式建模:

type Config struct {
    IName string `yaml:"i_name"`
    Instances []struct{
        Name string
        Command string
        Arguments map[string]interface{}
        Labels map[string]string
    }
}

    var c Config
    if err := yaml.Unmarshal(in, &c); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", c)
    fmt.Printf("%+v\n", c.Instances[0].Arguments["password"])
$ go run main.go

{IName:example Instances:[{Name:test-instance Command:get Arguments:map[hostname:localhost port:203 username:test password:testing123] Labels:map[env:dev]}]}
testing123

关于go - 如何从 map 界面解析特定键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55635827/

相关文章:

http - MIME ParseMediaType 在多部分边界上失败

bash - 使用 Go 从 "nc -e/bin/bash"生成带有 TTY 的 shell

validation - 如何从 Gin 绑定(bind)/验证中获取错误字段?

xml.Unmarshall 多根 XML 在 Go

mongodb - Mongod 无法识别 yaml 配置中的 net.http?

go - 如何在json中按深层排序在mongo中获取20个文档?

aws-lambda - lambda 函数内的跨堆栈引用

docker - yaml.parser.ParserError-为什么不起作用?

json - 如何从 Cloud Workflows 实例返回特定项目?

internationalization - 下一个JS : next-translate and yaml loader