ruby - 使用 ruby​​ 从 yml 文件中提取数据

标签 ruby parsing yaml

我阅读了一些关于 Yaml 或 yml 文件格式的快速教程。我制作了一个 yaml 文档来表示我的数据。我看到一些 ruby​​ 教程告诉你如何用 ruby​​ 提取 yaml。不幸的是,他们只是打印整个数据或只是键和值。它不符合我的需要。请帮忙。

yaml 文件 -

dev:
  game1:
    server1:
        url: 'dev-game1-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game1-a-srv02.gamer.com'
        log-path: '/srv/logs'

  game2:
    server1:
        url: 'dev-game2-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game2-b-srv02.gamer.com'
        log-path: '/srv/logs'
    server3:
        url: 'dev-game2-b-srv01.gamer.com'
        log-path: '/srv/logs'
prod: 
etc....

如何使用 ruby​​ 代码选择 dev、game2、server 3、url?

使用下面的代码,我得到一个异常 -

require 'yaml'

def server_info
    path = 'C:\Code\demo-srv.yml'
    yml = YAML::load(File.open(path))
    game2 = yml['dev']['game2'] 
    game2.each{|server|
        if server['server3']
            puts server['server3']['url']
        end
    }
end

server_info

错误-

server.rb:8:in `[]': can't convert String into Integer (TypeError)
        from server.rb:8:in `server_info'
        from server.rb:7:in `each'
        from server.rb:7:in `server_info'
        from server.rb:14

最佳答案

您是否定义了 yaml 数据,或者您只是现有 yaml 文件的使用者?

如果您定义了它,我会用哈希替换服务器数组(请参阅服务器名称前缺少的 -):

dev:
  game1:
    server1:
        url: 'dev-game1-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game1-a-srv02.gamer.com'
        log-path: '/srv/logs'

  game2:
    server1:
        url: 'dev-game2-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game2-b-srv02.gamer.com'
        log-path: '/srv/logs'
    server3:
        url: 'dev-game2-b-srv01.gamer.com'
        log-path: '/srv/logs'

然后你可以试试yml['dev']['game2']['server3']['url']

注意:不检查丢失/错误的数据。如果 game2 的条目未命中,此代码将引发异常。

所以,也许你应该做类似的事情

if yml['dev'] and yml['dev'].kind_of?(Hash)
  if yml['dev']['game2'] and ....
  ...
else
  puts "No dev-branch defined"
end

否则你可以尝试这样的事情:

def server_info
    yml = YAML::load(DATA)
    yml['dev']['game2'].each{|server|
      if server['server3']
        p server['server3']['url']
      end
    }
end

注意(对于两种解决方案):

不检查丢失/错误的数据。此处检查 server['server3'] 是否存在。对于真实代码,您还应该检查 devgame2 数据是否存在。


编辑后继续回答:

错误 convert String into Integer 如果您有一个数组但需要一个散列并且您尝试使用字符串访问数组元素,则通常会抛出此错误。

你可以试试下面的代码。有两个变化:

  • 第 8 行包含 server 的输出 - 您会看到它是一个数组,没有散列。
  • 第 9+10 行:检查数组并由其两个元素使用(通过#first 和#last)

    require 'yaml'
    
    def server_info
        path = 'C:\Code\demo-srv.yml'
        #~ yml = YAML::load(File.open(path))
        yml = YAML::load(DATA)
        game2 = yml['dev']['game2'] 
        game2.each{|server|
            p server    #-> you get an array
            if server.first == 'server3'
                puts server.last['url']
            end
        }
    end
    
    server_info
    

文件-

dev:
  game1:
    server1:
        url: 'dev-game1-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game1-a-srv02.gamer.com'
        log-path: '/srv/logs'

  game2:
    server1:
        url: 'dev-game2-a-srv01.gamer.com'
        log-path: '/srv/logs'
    server2:
        url: 'dev-game2-b-srv02.gamer.com'
        log-path: '/srv/logs'
    server3:
        url: 'dev-game2-b-srv01.gamer.com'
        log-path: '/srv/logs'

关于ruby - 使用 ruby​​ 从 yml 文件中提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29451006/

相关文章:

json - 有没有一种简单的方法可以使GORM错误的静态API友好

parsing - 如何在 Go 的文本/扫描仪中倒带?

ubuntu-14.04 - ansible 条件 "when"不适用于角色

ruby - 将重试的 sidekiq 作业放在队列的开头

ruby-on-rails - 运行 Rails 服务器时出错 - 如何更改 ruby​​gem 环境的默认 ruby​​?

ruby - 如何使用字符串访问运行时设置的变量?

ruby - 使用 pry-byebug 时如何在 pry 循环中使用下一条语句

perl - 从目录中读取一些变量 - 为了用 Mechanize 解析它们

spring-boot - 使用 Maven 将环境变量传递给 Spring Boot 应用程序

java - 使用 SnakeYAML 从不受信任的来源加载 YAML 文件时会发生什么?