我正在研究一个解决方案,它涉及yaml文件中的嵌套键。该软件将读取args中传递的文件并按顺序加载它们更新/添加密钥。
我有2 yaml文件,我想合并它们而不丢失任何关键。我想堆栈所有的配置文件,以生成一个单一的Map,而不删除任何关键字。
所以我有yaml 1
env: test1
template:
app:
database:
name: oracle
yaml2
env: test2
template:
app:
database:
version : 12
我想要的结果是(顺序为yaml 1-yaml 2)
env: test2
template:
app:
database:
name: oracle
version: 12
我试着用Map来复制,但由于键的名称相同,我最终得到了
env: test2
template:
app:
database:
version: 12
我在用
gopkg.in/yaml.v3读取yamls与给我Map[字符串]接口{}
和Map以使用副本
package main
import (
"fmt"
"log"
"maps"
"os"
"path/filepath"
"gopkg.in/yaml.v3"
)
type configuration struct {
c m
fl []string
}
type m = map[string]interface{}
func (c *configuration) Update(nc m) {
if c.c == nil {
c.c = nc
} else {
maps.Copy(c.c, nc)
}
}
func (c configuration) Print() {
d, err := yaml.Marshal(&c.c)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("---:\n%s\n\n", string(d))
}
func (c configuration) ParseDir(path string) {
}
func (c *configuration) LoadFromFile(filename string) {
// YAML string stored in a variable
yf, yfErr := os.ReadFile(filename)
if yfErr != nil {
log.Fatal("Error reading the file ", yfErr)
}
// Map to store the parsed YAML data
var data m
// Unmarshal the YAML string into the data map
err := yaml.Unmarshal(yf, &data)
if err != nil {
log.Fatal(err)
}
c.Update(data)
}
func listFiles(path string) []string {
var returnLf []string
err := filepath.Walk(path,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Mode().IsRegular() {
returnLf = append(returnLf, path)
}
return nil
})
if err != nil {
log.Println(err)
}
return returnLf
}
1条答案
按热度按时间5vf7fwbs1#
假设你想合并两个YAML文档中以“template”为键的YAMLMap,一个相当简单的实现如下所示:
Playground link。
mergeMapsRecursively
函数递归地合并两个map中的字段,如果它们都是map,或者用src
中的值替换dst
中的值,否则-就像maps.Copy
一样。如果这不是你所要求的,我希望我的例子能让你走上正确的道路。