Ruby -在分析文件的同时保持跨多行连接数据的跟踪



我正在编写一个脚本,从配置数据分布在多行中的文件中解析出某些值,并且在Ruby中遇到了很多麻烦。数据如下所示。将数据联系在一起的部分是单元号。我需要做的是从这个数据中抓取Unit, adminpaddress, 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+),AdminIPAddresss+{(.*)}/)
    temp = result.captures
    ip_array += [ temp ]
    printf "I captured #{temp}n"
  end
  if result = line.match(/W[a|r]TestProfile,Unit(?:d+),Interface,0,InterfaceDisplayStrings+{(.*)}/)
    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,Names+{(.*)}/)
    temp = result.captures
    name_array += [ temp ]
    printf "Finally, I captured #{temp}n"
  end
end

这将所有内容放入三个单独的数组中:从Unit 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}

所以我认为这可能是你正在寻找的,虽然它是有点难以理解的问题。这是我的解决方案,我会把每一部分都过一遍。

hsh = Hash.new()
File.open('config.txt', 'r').each_line do |line|
  match =
  /WaTestProfile,
    (?<unit>Unitd+)  # 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()

然后打开文件进行读取,并读取每一行。我们尝试在每一行中找到匹配项。这里我使用了一种更高级的regex形式,使用命名捕获并忽略空白,因为它有点复杂,因此更容易阅读
  match =
  /WaTestProfile,
    (?<unit>Unitd+)  # 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>Unitd+),.*(?<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"}}

相关内容

  • 没有找到相关文章

最新更新