我正在读取yaml文件,并将其解编为map[interface{}]interface{}
。目标是替换yaml中的某个值,并仅替换该值来更新读入的文件。我不确定如何解析地图以获取要更改的特定键(password
)。我相信您可以使用reflect
,但我不确定语法100%
我正在读(config.yml
)的YAML文件:
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)
答案 0 :(得分:1)
下面显示了如何逐步检查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