简体   繁体   中英

How to write items from Ruby objects to file

I have an array composed by three Ruby objects and each object represents an entity and each entity has an internal AS number, public and private ranges of IP addresses. The array looks like this:

entities = [#<Entity:0x0000000288a570 @name="entity-A",@internal_asn_number=64513, @public_range=["240.28.56.0-240.28.56.255", "250.154.64.0-250.154.64.255", "251.154.65.0-251.154.65.255"], @private_range=["16.1.1.1-16.1.1.254"]>,     #<Entity:0x000000028839a0 @name="entity-B", @internal_asn_number=64514, @public_range=["195.65.46.0-195.65.46.255","196.2.84.0-196.2.84.255","197.13.105.0-197.13.105.255"], @private_range=["11.2.1.1-11.2.1.254"]>,     #<Entity:0x0000000287b0c0 @name="entity-C", @internal_asn_number=64512, @public_range=["102.206.119.0-102.206.119.255", "103.206.12.0-103.206.12.255", "104.28.90.0-104.28.90.255"], @private_range=["2.1.1.1-2.1.1.254"]>]

I save the the IP ranges into one unique variable, so I can then transform the ranges into the CIDR format and merge them. Then I save the final result into an array. Finally, I try to write the output into a file in the format (merged IP address/AS number):

240.28.56.0/24   64513
250.154.64.0/24  64513
251.154.65.0/24  64513
16.1.1.1/32  64513

And I have the following code:

require 'netaddr'

cidrs = Array.new

File.open('out.dat', "w") do |f|
    entities.each do |entity|
      asn = entity.internal_asn_number
      ranges = entity.public_range + entity.private_range
      ranges.each do |ip_range|
        new_range = ip_range.split(/\s*-\s*/)
        startip = new_range[0]
        endip = new_range[1]
        ip_net_range = NetAddr.range(startip, endip, :Inclusive => true, :Objectify => true)
        cidrs << NetAddr.merge(ip_net_range)
      end
      new_cidrs = cidrs.flatten
      new_cidrs.each do |ip|
        f.write("#{ip}\t #{asn}\n")
      end
   end
end

This code gives me the following output:

240.28.56.0/24   64513
250.154.64.0/24  64513
251.154.65.0/24  64513
16.1.1.1/32  64513
16.1.1.2/31  64513
16.1.1.4/30  64513
16.1.1.8/29  64513
16.1.1.16/28     64513
16.1.1.32/27     64513
16.1.1.64/26     64513
16.1.1.128/26    64513
16.1.1.192/27    64513
16.1.1.224/28    64513
16.1.1.240/29    64513
16.1.1.248/30    64513
16.1.1.252/31    64513
16.1.1.254/32    64513
240.28.56.0/24   64514
250.154.64.0/24  64514
251.154.65.0/24  64514
16.1.1.1/32  64514
16.1.1.2/31  64514
16.1.1.4/30  64514
16.1.1.8/29  64514
16.1.1.16/28     64514
16.1.1.32/27     64514
16.1.1.64/26     64514
16.1.1.128/26    64514
16.1.1.192/27    64514
16.1.1.224/28    64514
16.1.1.240/29    64514
16.1.1.248/30    64514
16.1.1.252/31    64514
16.1.1.254/32    64514
195.65.46.0/24   64514
196.2.84.0/24    64514
197.13.105.0/24  64514
11.2.1.1/32  64514
11.2.1.2/31  64514
11.2.1.4/30  64514
11.2.1.8/29  64514
11.2.1.16/28     64514
11.2.1.32/27     64514
11.2.1.64/26     64514
11.2.1.128/26    64514
11.2.1.192/27    64514
11.2.1.224/28    64514
11.2.1.240/29    64514
11.2.1.248/30    64514
11.2.1.252/31    64514
11.2.1.254/32    64514
240.28.56.0/24   64512
250.154.64.0/24  64512
251.154.65.0/24  64512
16.1.1.1/32  64512
16.1.1.2/31  64512
16.1.1.4/30  64512
16.1.1.8/29  64512
16.1.1.16/28     64512
16.1.1.32/27     64512
16.1.1.64/26     64512
16.1.1.128/26    64512
16.1.1.192/27    64512
16.1.1.224/28    64512
16.1.1.240/29    64512
16.1.1.248/30    64512
16.1.1.252/31    64512
[...]

Basically, the IP addresses are written to the file three times, and what I was expecting was to have the merged IP addresses from entity-A with the AS number of entity-A and so on.

I don't know what I'm doing wrong.

The reason you get duplicate entries is that the cidrs array is declared before you loop through each entity, so the second entity has all of the first entities as well as its own and so on.

If you move the cidrs array declaration into the entity loop it seems to work:

File.open('out.dat', "w") do |f|
    entities.each do |entity|
        cidrs = Array.new

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM