Convert IP ranges to discrete ip numbers with bash / awk / sed

I process the lists of IP sources / receivers / ports created as acl requests. The request looks something like this:

source IP    destination IP  Port
76.211.12.9  10.112.12.232   1521

Source and destination IDs have three different formats

  • h.kh.kh.kh, y, g
  • hhhhh
  • h.kh.kh.kh, yyyy, g, g, g, g

I want to create a conclusion

  • xx.x.x
    xxxy
    xxxz
  • xx.x.x
    xxxy
    xxxz
  • hhhh
    yyyy
    zzzz

using bash, sed, awk, how can I do this? in my example:

76.211.12.9,10,11 10.112.12.232 1521
76.211.12.9-11 10.112.12.232 1521

Both outputs will look like this:

76.211.12.9 10.112.12.232 1521
76.211.12.10 10.112.12.232 1521
76.211.12.11 10.112.12.232 1521
+3
source share
3 answers
BEGIN { DEBUG = 0 }

function setup(first_split, second_split) {
  src = $1; dst = $2; port = $3
  j = split(src, src_a, first_split)
  k = split(src_a[4], src_a_2, second_split)
  if(DEBUG)
    print "<" first_split second_split ">", j, k, "\n" src
}

/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*,[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/ {
  setup(",", ",")
  for(i = 1; i <= j; ++i)
    print src_a[i], dst, port
  next
}

/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*,[0-9][0-9]*[ ,]/ {
  setup(".", ",")
  for(i = 1; i <= k; ++i)
    print src_a[1] "." src_a[2]"." src_a[3] "." src_a_2[i], dst, port
  next
}

/^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*-/ {
  setup(".", "-")
  for(i = src_a_2[1]; i <= src_a_2[2]; ++i)
    print src_a[1] "." src_a[2] "." src_a[3] "." i, dst, port
  next
}

{ print }

My test file:

76.211.77.7 10.112.12.232 1521
76.211.77.8 10.112.12.232 1521
76.211.77.9,10,11 10.112.12.232 1521
76.211.77.12-13 10.112.12.232 1521
76.211.77.14,76.211.77.15,76.211.77.16 10.112.12.232 1521

This script will work in One True Awk as well as with gawk.

+1
source

awk , , awk .

awk , 1970 , Unix, Renaissance. Unix, , , Ruby...

Ruby , . Awk...

class IPMacro
  private_class_method :new
  def self.get_base a
    @@root = a[0].split('.').tap { |x| @@last = x[3] || x[0] }.take(3).join('.')
  end
  def self.expand_last_comma a
    self.get_base a
    [a[0], *(a.drop(1).map { |e| [@@root, e].join('.') })]
  end
  def self.expand_last_dash a
    self.get_base a
    @@root = @@root['.'] ? [@@root] : []
    [*(@@last..a[1]).to_a.map do |e|
        (@@root +  [String(e)]).join '.'
      end
    ]
  end
  def self.expand f
    a = f.split ','
    if a[1]
      return self.expand_last_comma a unless a[1]['.'] || !a[0]['.']
    else
      a = f.split '-'
      return self.expand_last_dash a if a[1]
    end
    return [*a]
  end
  def self.run
    $<.each_line do |line|
      a = line.split(' ').map do |f|
        self.expand f
      end
      a[0].each do |a1|
        a[1].each do |a2|
          a[2].each do |a3|
            puts '%s %s %s' % [a1, a2, a3]
          end
        end
      end
    end
  end
  self
end.run

...

76.211.77.5 10.112.12.227 1400,1401,1402
76.211.77.6 10.112.12.228-231 1510-1515
76.211.77.7 10.112.12.232 1521
76.211.77.8 10.112.12.232 1521
76.211.77.9,10,11 10.112.12.232 1521
76.211.77.12-13 10.112.12.232 1521
76.211.77.14,76.211.77.15,76.211.77.16 10.112.12.232 1521
+1

! - . .. , . 340 7500 src/dest/port.

0

Source: https://habr.com/ru/post/1771119/


All Articles