2016-09-22 4 views
3

Это мой YAML файл:Golang: Получить Вложенные ключи в YAML

hosts: all 
gather_facts: no 
remote_user: ubuntu 
name: install latest nginx 
tasks: 
    - name: install the nginx key 
    apt_key: 
     url: http://nginx.org/keys/nginx_signing.key 
     state: present 
    become: yes 

    - name: install aws cli 
    command: pip3 install awscli 
    become: yes 

Это мой код:

package main 

import (
    "github.com/davecgh/go-spew/spew" 
    "gopkg.in/yaml.v2" 
    "io/ioutil" 
) 

type Config struct { 
    Hosts  string    `yaml:hosts` 
    Gather_facts string    `yaml:gatherfacts` 
    Remote_user string    `yaml:remoteuser` 
    Name   string    `yaml:names` 
    Tasks  []map[string]string `yaml:tasks` 
} 

func main() { 
    file, err := ioutil.ReadFile("/path-to-nginx1.yml") 
    if err != nil { 
     panic(err) 
    } 
    var config Config 
    yaml.Unmarshal(file, &config) 
    spew.Dump(config) 
} 

А вот выход:

(main.Config) { 
Hosts: (string) (len=3) "all", 
Gather_facts: (string) (len=2) "no", 
Remote_user: (string) (len=6) "ubuntu", 
Name: (string) (len=20) "install latest nginx", 
Tasks: ([]map[string]string) (len=2 cap=2) { 
    (map[string]string) (len=2) { 
    (string) (len=6) "become": (string) (len=3) "yes", 
    (string) (len=4) "name": (string) (len=21) "install the nginx key" 
    }, 
    (map[string]string) (len=3) { 
    (string) (len=4) "name": (string) (len=15) "install aws cli", 
    (string) (len=7) "command": (string) (len=19) "pip3 install awscli", 
    (string) (len=6) "become": (string) (len=3) "yes" 
    } 
} 
} 

ВОПРОС: Как получить под клавишами из YAML?

apt_key: 
    url: http://nginx.org/keys/nginx_signing.key 
    state: present 

На данный момент мой Go анализатор полностью пропускает выше ключи от выхода.

Кроме того, у меня есть много файлов YAML с разной степенью гнездования в них всех. Большинство из них имеют разную степень вложенности внутри самого файла. Нужно ли мне изменить мой struct, чтобы адресовать каждый отдельный ключ? ИЛИ, Что лучше способ иметь дело с YAML файлами с разным уровнем вложенности для каждой клавиши?

>>> UPDATE < < <:

Я сделал некоторый прогресс, изменяя мой Tasks внутри struct, как показано ниже:

type Config struct { 
    Hosts  string `yaml:hosts` 
    Gather_facts string `yaml:gatherfacts` 
    Remote_user string `yaml:remoteuser` 
    Name   string `yaml:names` 
    Tasks  []struct { 
     Name string `yaml:name` 
     Apt_key struct { 
      Url string `yaml:url` 
      State string `yaml:url` 
     } `yaml:apt_key` 
     Become string `yaml:become` 
    } 
} 

Выход:

(main.Config) { 
Hosts: (string) (len=3) "all", 
Gather_facts: (string) (len=2) "no", 
Remote_user: (string) (len=6) "ubuntu", 
Name: (string) (len=20) "install latest nginx", 
Tasks: ([]struct { Name string "yaml:name"; Apt_key struct { Url string "yaml:url"; State string "yaml:url" } "yaml:apt_key"; Become string "yaml:become" }) (len=2 cap=2) { 
    (struct { Name string "yaml:name"; Apt_key struct { Url string "yaml:url"; State string "yaml:url" } "yaml:apt_key"; Become string "yaml:become" }) { 
    Name: (string) (len=21) "install the nginx key", 
    Apt_key: (struct { Url string "yaml:url"; State string "yaml:url" }) { 
    Url: (string) (len=39) "http://nginx.org/keys/nginx_signing.key", 
    State: (string) (len=7) "present" 
    }, 
    Become: (string) (len=3) "yes" 
    }, 
    (struct { Name string "yaml:name"; Apt_key struct { Url string "yaml:url"; State string "yaml:url" } "yaml:apt_key"; Become string "yaml:become" }) { 
    Name: (string) (len=15) "install aws cli", 
    Apt_key: (struct { Url string "yaml:url"; State string "yaml:url" }) { 
    Url: (string) "", 
    State: (string) "" 
    }, 
    Become: (string) (len=3) "yes" 
    } 
} 
} 

Так сейчас Я вижу apt_key которая полностью отсутствовала раньше. Однако, я не нахожу command часть, которая записывается в YAML как:

 command: pip3 install awscli 

Как я могу получить это?

Кроме того, у меня нет приятного ощущения, поскольку я должен объявить почти каждый ключ в struct, который в этом случае в порядке, так как мой YAML вряд ли длиннее 15 строк. Но это было бы уродливо и громоздко, если бы YAML было больше и длиннее. Я уверен, что должен быть лучший и эффективный способ в для обработки YAML файлов.

ответ

1

Кажется, что вы уже все закончили, вы просто пропустите Командная часть в определении конфигурации Config. Я видел, что другие ответы указывали на то, что у вас непоследовательные данные, это правильно, но вы можете получить их в одной и той же структуре, только отсутствующие поля будут пустыми, если они отсутствуют в файле yaml.

package main 

    import (
     "github.com/davecgh/go-spew/spew" 
     "gopkg.in/yaml.v2" 
     "io/ioutil" 
    ) 

    type Config struct { 
     Hosts  string `yaml:hosts` 
     Gather_facts string `yaml:gatherfacts` 
     Remote_user string `yaml:remoteuser` 
     Name   string `yaml:names` 
     Tasks  []struct { 
      Name string `yaml:name` 
      Apt_key struct { 
       Url string `yaml:url` 
       State string `yaml:url` 
      } `yaml:apt_key` 
      Become string `yaml:become` 
      Command string `yaml:command` 
     } 
    } 

    func main() { 
     file, err := ioutil.ReadFile("/home/bane/Desktop/go/a.yml") 
     if err != nil { 
      panic(err) 
     } 
     var config Config 
     yaml.Unmarshal(file, &config) 
     // spew.Dump(config) 
     spew.Dump(config.Tasks[0]) 
     spew.Dump(config.Tasks[1]) 
    } 
+0

Спасибо. +1. Я попробовал это и обнаружил, что 'command' отображается пустым в ключах, где он не существует. Я думал, что это неправильный способ сделать это. – slayedbylucifer

1

Это не работает, потому что вы пытаетесь распаковать два Differents набор: имя, APT-ключ, стать и имя, команда, становится использованием того же структуры. Это непоследовательно.

+0

Да. Я понимаю, что данные непоследовательны.Но это действительный 'YAML', и мой фактический' YAML' намного длиннее этого с еще более несогласованными ключами. Не могли бы вы предложить, как я могу справиться с этим. – slayedbylucifer

+1

Можно использовать две отдельные структуры –

+1

Если вы не можете ограничивать только двумя структурами, вы можете попробовать получить все ключи, а затем получить значения из этих ключей. –

Смежные вопросы