本周在工作中,我遇到了解析特定文件格式的挑战包含按不同站点、区域和区域分类的IP范围地区。基本上,我需要一个脚本将所有这些位置信息加载到数据结构,这样我就可以很容易地获得所有的ip用于以后的转换的站点、区域或区域。
<>之前所需数据结构:data[Region][Area][Site] -> ip地址哈希数组之前我想知道函数"processLocations"是否可以优化的,或者如果有更简单的方法来实现所需的数据结构。特别是在创建"数组的哈希的哈希的哈希"区域变量时。
希望这也可以帮助其他人在相同的情况下,所以这是一个我目前的工作副本:
require 'pp'
# Function that processes the content of the locations file and returns
the following structure:
#
# data[Region][Area][Site] -> IPs
# Hash Hash Hash Array
#
def processLocations (lines)
sites = Hash.new{|h, k| h[k] = []} # HashOFArray
area = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)} # HashOFHash
region = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)} # HashOFHash
lines.each do |line|
next if lines =~ /^#.*/
# Process IPs range section
if line =~ /(.*)=([d|-|.]+)/
#puts "IP: #{$1} - #{$2}"
sites[$1.chomp.capitalize] << $2
end
# Process area section
if line =~ /(.*).area=(.*)/i
#puts "Area: #{$1} - #{$2}"
if sites.has_key?($1.chomp.capitalize)
if (area.has_key?($2.chomp.capitalize) &
area[$2.chomp.capitalize].has_key?($1.chomp.capitalize))
# The hash exists
#puts "Adding to an existing hash key more IPs elements to the
array"
area[$2.chomp.capitalize][$1.chomp.capitalize] <<
sites[$1.chomp.capitalize]
else
# The hash does not exist
#puts "Adding new hash key with new array"
area[$2.chomp.capitalize][$1.chomp.capitalize] =
sites[$1.chomp.capitalize]
end
# Clean site hash
sites = Hash.new{|h, k| h[k] = []} # HashOFArray
end
end
# Process region section
if line =~ /(.*).region=(.*)/i
#puts "Region: #{$1} - #{$2}"
if area.has_key?($1.chomp.capitalize)
tmp = Hash.new
tmp = area.dup
region[$2.chomp.capitalize][$1.chomp.capitalize] =
tmp[$1.chomp.capitalize]
end
end
end
return region
end
##############
# MAIN
f = File.open(DATA)
lines = f.readlines
f.close
data = processLocations(lines)
puts "+data---------------------------------------------------------"
pp data
puts "+data['Asia']-------------------------------------------------"
pp data['Asia']
puts "+data['Asia']['Australia']------------------------------------"
pp data['Asia']['Australia']
puts "+data['Europe-middle east-africa']['France']['Paris']---------"
pp data['Europe-middle east-africa']['France']['Paris']
__END__
Alexandria (ALH)=192.168.6.0-192.168.6.127
Alexandria (ALH).area=Australia
Australia.region=Asia
Altona=192.168.1.192-192.168.1.255
Altona=192.168.2.192-192.168.2.255
Altona.area=Australia
TOKYO VPN=192.168.3.192-192.168.3.255
TOKYO VPN.area=JAPAN
JAPAN.region=Asia
Paris=192.168.4.192-192.168.4.255
Paris.area=France
Rennes=192.168.5.192-192.168.5.255
Rennes.area=France
France.region=EUROPE-MIDDLE EAST-AFRICA
示例输出:
# ruby ruby_help.rb
+data---------------------------------------------------------
{"Asia"=>
{"Australia"=>
{"Alexandria (alh)"=>["192.168.6.0-192.168.6.127"],
"Altona"=>["192.168.1.192-192.168.1.255",
"192.168.2.192-192.168.2.255"]},
"Japan"=>{"Tokyo vpn"=>["192.168.3.192-192.168.3.255"]}},
"Europe-middle east-africa"=>
{"France"=>
{"Paris"=>["192.168.4.192-192.168.4.255"],
"Rennes"=>["192.168.5.192-192.168.5.255"]}}}
+data['Asia']-------------------------------------------------
{"Australia"=>
{"Alexandria (alh)"=>["192.168.6.0-192.168.6.127"],
"Altona"=>["192.168.1.192-192.168.1.255",
"192.168.2.192-192.168.2.255"]},
"Japan"=>{"Tokyo vpn"=>["192.168.3.192-192.168.3.255"]}}
+data['Asia']['Australia']------------------------------------
{"Alexandria (alh)"=>["192.168.6.0-192.168.6.127"],
"Altona"=>["192.168.1.192-192.168.1.255",
"192.168.2.192-192.168.2.255"]}
+data['Europe-middle east-africa']['France']['Paris']---------
["192.168.4.192-192.168.4.255"]
对任何建议提前表示敬意和感谢,
Sebastian耶佩斯我同意Mu的观点,你可以建立一些类,但我认为这应该工作:
def processLocations (lines)
sites = Hash.new{|h, k| h[k] = []}
areas = Hash.new{|h, k| h[k] = {}}
regions = Hash.new{|h, k| h[k] = {}}
lines.each do |line|
case line
# Process IPs range section
when /(.*)=([d|-|.]+)/
sites[$1.chomp.capitalize] << $2
# Process area section
when /(.*).area=(.*)/i
site_key, area = $1.chomp.capitalize, areas[$2.chomp.capitalize]
area[site_key] = sites[site_key]
# Process region section
when /(.*).region=(.*)/i
area_key, region = $1.chomp.capitalize, regions[$2.chomp.capitalize]
region[area_key] = areas[area_key]
when /^#.*/ # do nothing
else
# error?
end
end
regions
end