我正在尝试编写一个单行程序来从VirtualBox的主机接口列表的输出创建一个哈希。它看起来像这样
Name: vboxnet0
GUID: 77777777-6666-4444-8888-020227202302
DHCP: Disabled
IPAddress: 192.168.42.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:00
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet0
Name: vboxnet1
GUID: 77777777-6666-4444-8888-020227202301
DHCP: Disabled
IPAddress: 172.16.0.1
NetworkMask: 255.255.255.0
IPV6Address:
IPV6NetworkMaskPrefixLength: 0
HardwareAddress: 0a:00:27:00:00:01
MediumType: Ethernet
Status: Up
VBoxNetworkName: HostInterfaceNetworking-vboxnet1
我试过了:
Hash[*`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1)]
结果是:
=> {"Name"=>"vboxnet1", "GUID"=>"786f6276-656e-4174-8000-0a0027000001", "DHCP"=>"Disabled", "IPAddress"=>"172.16.0.1", "NetworkMask"=>"255.255.255.0", "IPV6Address"=>"IPV6NetworkMaskPrefixLength", "0"=> "HardwareAddress", "0a"=>"00", "27"=>"00", "00"=>"01", "MediumType"=>"Ethernet", "Status"=>"Up", "VBoxNetworkName"=>"HostInterfaceNetworking-vboxnet1"}
几乎是我想要的,但仅限于第一个界面。我在想:“好吧,将数组切成两半并将每一半转换为哈希!”。
我的问题是如何获得flatten方法返回的Array的大小,并在slice方法的参数中使用它而不将其赋值给变量等?
我的意思是:
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten(1).slice(0..>>>how_to_access_result_object_of_flatten_here<<<.size/2)
我不是那种经验丰富的Ruby,所以很抱歉,如果问题很明显,但我尝试了很多谷歌搜索无济于事。
编辑:?closure / lambda中split
的正则表达式?传递给collect
是不对的,因为它只返回一个字符串(应该是两个用于哈希转换才能工作),如果在冒号之后只有空格,那么以IPV6Address:
开头的行就是这种情况(在示例中不可见)。我将其更改为split(/:\ /)
,现在可以正常工作了。需要空间,因为只使用冒号也会分割MAC地址。
答案 0 :(得分:1)
除非有一些我从未见过的特殊的Ruby巫术,否则我很确定简单的答案就是你不能。
但是,下一个最好的方法(而不是将数组赋值给变量)是扩展Array
类并编写一个额外的方法,如下所示:
class Array
def flatten_and_slice
flattened_result = self.flatten(1)
self.slice(0..flattened_result.size/2)
end
end
然后你只需要调用你的新方法。
`VBoxManage list hostonlyifs`.split("\n").reject(&:empty?).collect {|s| s.split(/:\ */)}.flatten_and_slice
答案 1 :(得分:1)
您可以按^$
拆分输出并选择所需的界面:
text = `VBoxManage list hostonlyifs`
Hash[*text.split(/^$/)[0].split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }]
text.split(/^$/)[0]
将文本分割为空行并接受第一个界面。然后,我们只需将该文本解析为散列,然后将其拆分为单独的行,分成[key,value]对,并将其映射为Hash。这给出了如下输出:
{
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
}
如果要生成一个哈希数组,每个接口一个,分割文本,然后将每个文本块映射到哈希:
text.split(/^$/).map {|chunk| Hash[*chunk.split(/\n/).flat_map {|line| line.split(":", 2).map(&:strip) }] }
导致:
[
[0] {
"Name" => "vboxnet0",
"GUID" => "77777777-6666-4444-8888-020227202302",
"DHCP" => "Disabled",
"IPAddress" => "192.168.42.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:00",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet0"
},
[1] {
"Name" => "vboxnet1",
"GUID" => "77777777-6666-4444-8888-020227202301",
"DHCP" => "Disabled",
"IPAddress" => "172.16.0.1",
"NetworkMask" => "255.255.255.0",
"IPV6Address" => "",
"IPV6NetworkMaskPrefixLength" => "0",
"HardwareAddress" => "0a:00:27:00:00:01",
"MediumType" => "Ethernet",
"Status" => "Up",
"VBoxNetworkName" => "HostInterfaceNetworking-vboxnet1"
}
]