我正在编写一个脚本来解析文件中的某些值,其中配置数据分布在多行中,并且在Ruby中执行它时遇到了很多麻烦。数据如下所示。将数据绑定在一起的部分是单元号。我需要做的是从这些数据中获取Unit,AdminIPAddress,InterfaceDisplayString和Name值,并以有意义的方式保存它。对我来说,多维Perl哈希是完美的,但语法超出了我对Ruby语言的理解。
非常感谢您提供的任何帮助。我希望将数据放在哈希中,如下所示:
{Unit0} => {IPAddress => 10.5.52.60, Name => 440_6PT_6AS_inf4, Port = 10_10},
{Unit1} => ...
通过执行以下操作,我已经能够创建所有重要行的数组:
if (line =~ /WaTestProfile,Unit[\d+]/)
# Manipulate the data first to remove pesky special characters
result = line.gsub(/[^0-9A-Za-z,\.\,\{\}\_ ]/, '')
if result !~ /DDOS|PhysIf/
temp_line += [ "#{result}" ]
end
end
然后我可以使用一些正则表达式来提取特定的字段:
unit_array.sort.each_with_index do |line, idx|
if result = line.match(/W[a|r]TestProfile,Unit(?:\d+),AdminIPAddress\s+\{(.*)\}/)
temp = result.captures
ip_array += [ temp ]
printf "I captured #{temp}\n"
end
if result = line.match(/W[a|r]TestProfile,Unit(?:\d+),Interface,0,InterfaceDisplayString\s+\{(.*)\}/)
temp = result.captures
port_array += [ temp]
printf "I have captured #{temp}\n"
end
if result = line.match(/W[a|r]TestProfile,Unit(?:\d+),Interface,0,Name\s+\{(.*)\}/)
temp = result.captures
name_array += [ temp ]
printf "Finally, I captured #{temp}\n"
end
end
这将所有内容分成三个独立的数组:从0到5的最低位,但是我不能将它带到下一步并将它们放在多维数组中,我认为上面的代码也可能是改善。
WaTestProfile,Unit0,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit0,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit0,Interface,0,DDOSConfig {}\
WaTestProfile,Unit0,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit0,Interface,0,InterfaceDisplayString {10_10}\
WaTestProfile,Unit0,Interface,0,Name {440_6PT_6AS_inf5}\
WaTestProfile,Unit0,Interface,0,PhysIf {10}\
WaTestProfile,Unit1,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit1,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit1,Interface,0,DDOSConfig {}\
WaTestProfile,Unit1,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit1,Interface,0,InterfaceDisplayString {8_8}\
WaTestProfile,Unit1,Interface,0,Name {440_6PT_6AS_inf4}\
WaTestProfile,Unit1,Interface,0,PhysIf {8}\
WaTestProfile,Unit2,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit2,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit2,Interface,0,DDOSConfig {}\
WaTestProfile,Unit2,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit2,Interface,0,InterfaceDisplayString {2_2}\
WaTestProfile,Unit2,Interface,0,Name {440_6PT_6AS_inf1}\
WaTestProfile,Unit2,Interface,0,PhysIf {2}\
WaTestProfile,Unit3,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit3,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit3,Interface,0,DDOSConfig {}\
WaTestProfile,Unit3,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit3,Interface,0,InterfaceDisplayString {4_4}\
WaTestProfile,Unit3,Interface,0,Name {440_6PT_6AS_inf2}\
WaTestProfile,Unit3,Interface,0,PhysIf {4}\
WaTestProfile,Unit4,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit4,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit4,Interface,0,DDOSConfig {}\
WaTestProfile,Unit4,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit4,Interface,0,InterfaceDisplayString {6_6}\
WaTestProfile,Unit4,Interface,0,Name {440_6PT_6AS_inf3}\
WaTestProfile,Unit4,Interface,0,PhysIf {6}\
WaTestProfile,Unit5,AdminIPAddress {10.5.52.60}\
WaTestProfile,Unit5,Interface,0,DDOSAttacks {}\
WaTestProfile,Unit5,Interface,0,DDOSConfig {}\
WaTestProfile,Unit5,Interface,0,DDOSEnabled {off}\
WaTestProfile,Unit5,Interface,0,InterfaceDisplayString {0_0}\
WaTestProfile,Unit5,Interface,0,Name {440_6PT_6AS_inf0}\
WaTestProfile,Unit5,Interface,0,PhysIf {0}\
答案 0 :(得分:0)
所以我认为这可能是你正在寻找的东西,尽管很难理解这个问题。这是我的解决方案,我将逐一介绍。
hsh = Hash.new()
File.open('config.txt', 'r').each_line do |line|
match =
/WaTestProfile,
(?<unit>Unit\d+) # match the unit and unit number
,.* # match the comma and all the way up to the property
(?<property>AdminIPAddress|InterfaceDisplayString|Name) # match the property
\s+ # match all spaces up to the property value
{(?<property_value>.*)} # match the property value
/x =~ line
if match
hsh[unit.to_sym] ||= {}
hsh[unit.to_sym][property.to_sym] = property_value
end
end
hsh.each do |key, value|
puts key.to_s + value.to_s
end
所以这只是创建一个哈希,我们也可以做hsh = {}
hsh = Hash.new()
然后我们打开文件进行阅读并读取每一行。在每一行我们都试图找到匹配。我在这里使用了更高级的正则表达式,使用了命名捕获并忽略了空格,因为它更复杂,所以它更容易阅读
match =
/WaTestProfile,
(?<unit>Unit\d+) # match the unit and unit number
,.* # match the comma and all the way up to the property
(?<property>AdminIPAddress|InterfaceDisplayString|Name|PhysIf) # match the property
\s+ # match all spaces up to the property value
{(?<property_value>.*)} # match the property value
/x =~ line
现在我可以引用变量unit
并获取整个单位和单位编号
我们还在开始时使用match =
,以便我们可以从等式中删除DDOS行。
最后我们检查是否有匹配。如果有,我们要么创建一个对应于顶级哈希中的哈希的新密钥,要么我们抓住现有的密钥。然后我们将属性设置为正确的属性值。我假设你没有在你希望它们成为符号的键周围加上引号,无论如何这可能是一个更好的主意。
if match
hsh[unit.to_sym] ||= {}
hsh[unit.to_sym][property.to_sym] = property_value
end
最终输出如下:
Unit0{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"10_10", :Name=>"440_6PT_6AS_inf5"}
Unit1{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"8_8", :Name=>"440_6PT_6AS_inf4"}
Unit2{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"2_2", :Name=>"440_6PT_6AS_inf1"}
Unit3{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"4_4", :Name=>"440_6PT_6AS_inf2"}
Unit4{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"6_6", :Name=>"440_6PT_6AS_inf3"}
Unit5{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"0_0", :Name=>"440_6PT_6AS_inf0"}
全部包含在哈希hsh
嘘:
如果你想要一个更短的版本,这里是:
hsh = {}
File.open('config.txt', 'r').each_line do |line|
if /WaTestProfile,(?<unit>Unit\d+),.*(?<property>AdminIPAddress|InterfaceDisplayString|Name)\s+{(?<property_value>.*)}/x =~ line
hsh[unit.to_sym] ||= {}
hsh[unit.to_sym][property.to_sym] = property_value
end
end
p hsh
输出:
{:Unit0=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"10_10", :Name=>"440_6PT_6AS_inf5"}, :Unit1=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"8_8", :Name=>"440_6PT_6AS_inf4"}, :Unit2=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"2_2", :Name=>"440_6PT_6AS_inf1"}, :Unit3=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"4_4", :Name=>"440_6PT_6AS_inf2"}, :Unit4=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"6_6", :Name=>"440_6PT_6AS_inf3"}, :Unit5=>{:AdminIPAddress=>"10.5.52.60", :InterfaceDisplayString=>"0_0", :Name=>"440_6PT_6AS_inf0"}}