Ruby-Script-contig_devs.rb

Print Friendly, PDF & Email

DISCLAIMER

This script is as is. I give no warranty it will work as you expected on your system. You are running it at your own risk. If something goes wrong because of this script, I bear no responsibility.

Language


server# ruby -v
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

Purpose

You have several device numbers in hexadecimal format – some as a range, some as single. You want to find out which devs are in sequence, and how many in a single sequence, and total number of devs.

Conditions

The device numbers given at command line must be hexadecimal (script will treat them as hexadecimal). Specify the devs with “:” if they are in range. Separate all devs by a comma. Example would be: 12AB:13AB,1123,5C6:5D7

Usage


# contig_devs.rb 4289,41EE,41EF,41F0,41F1,41F,420,41EE,41EF,41F0,41F1,41F2,41F3,4256,4257,4258,4259,425A

Devices    Count
========== =====
041F:0420      2
41EE:41F3      6
4256:425A      5
4289           1
========== =====
Total         14

041F:0420,41EE:41F3,4256:425A,4289

041F:0420,41EE:41F3,4256:425A,4289:4289

# cat contig_devs.rb
#!/export/home/user/software/ruby/bin/ruby
#************************************************************************************************#
#               A script to process given device numbers in hexadecimal format and
#               present them on screen in a contiguous range along with their counts
#               Written by  : Ketan Patel
# v01 - First Draft : 04/05/2015
#************************************************************************************************#

class ParseInput

  attr_reader :alldevs_dec_sorted

  def initialize
    @hexids                 = Array.new
        @alldevs_dec_sorted = Array.new
  end # end initialize

  def usage
    puts "  usage   : contig_devs.pl <entry> : <entry> is list of devs separated by commas, they can be in any sequence, and can contain range(s)
  example : contig_devs.pl 1200:120f,1300,1302:130f,1400 "
    exit
  end # usage end

  def checkInput (input)
    input.empty? ? ( self.usage ) : ( temphexids = input.first.split(",") )
        @hexids = temphexids.reject{ |e| e.empty? }
  end # checkInput end

  def goThroughInput
    alldevs_dec = Hash.new
    @hexids.each do |hexid|
      if hexid.include? ':'
        range    = hexid.split(":")
        range[0].empty? ? ( puts "Missing start value in range #{hexid}"; exit ) : ( firstdec = "#{range[0]}".hex)
        range.length == 1 ? ( puts "Missing end value in range #{hexid}"; exit ) : ( lastdec = "#{range[1]}".hex )
        if firstdec < lastdec
          (firstdec..lastdec).each do |decid|
            alldevs_dec[decid] = 1
          end
        else
          puts "ERROR: Invalid range #{hexid} - #{range[0]} is bigger than #{range[1]}"
          exit
        end
      else
        decid = hexid.hex
        alldevs_dec[decid] = 1
      end
    end
    @alldevs_dec_sorted = alldevs_dec.keys.sort 
    # this array contains all numbers given to script in sorted decimal format
  end # goThroughInput end

end  # class end

class DeviceBreakUp < ParseInput
  @@outlines = Hash.new
  @@devstr    = String.new
  @@rngstr    = String.new

  def prepareOPLines (firstdev,count,lastdev="")
        lastdev.empty? ? ( devs = firstdev; range = "#{firstdev}:#{firstdev}" ) : ( devs = "#{firstdev}:#{lastdev}"; range = devs )
        @@devstr.empty? ? ( @@devstr = devs ) : ( @@devstr = "#{@@devstr},#{devs}" )
        @@rngstr.empty? ? ( @@rngstr = range ) : ( @@rngstr = "#{@@rngstr},#{range}" )
        @@outlines[devs] = count
  end

  def headertailer (section)
    section == "header" ? (puts "\n%-10s %5s \n%-10s %5s" %["Devices", "Count","==========", "====="]) : ( )
    section == "tailer" ? (puts "%-10s %5s \n%-10s %5s" %["==========", "=====","Total", @alldevs_dec_sorted.length]) : ( )
  end # headertailer end

  def printOutput
    self.headertailer "header"
        @@outlines.each do |key,value|
      puts "%-10s %5s" %[key,value]
    end
        self.headertailer "tailer"
        puts "\n#{@@devstr}"
        puts "\n#{@@rngstr}\n"
  end # printOutput end

end

ip = DeviceBreakUp.new
ip.checkInput (ARGV)
ip.goThroughInput

cur_range_count    = 0
prev_range_count   = 0
dev_count          = 0
is_firstdev        = "yes"
total_devs         = ip.alldevs_dec_sorted.length
prevdev_dec        = 0
curdev_dec         = 0
range_lastdev_hex  = ""
cur_range_firstdev_hex = ""
pre_range_firstdev_hex = ""

ip.alldevs_dec_sorted.each do |curdev_dec|
  dev_count+=1
  #puts "\ndebug - dev being processed is #{curdev_dec}"
  if is_firstdev == "yes" # IF1
    #puts "  debug - inside IF1"
        cur_range_firstdev_hex = sprintf("%04X", curdev_dec)
        cur_range_count+=1

    if dev_count == total_devs # IF2 - only a single device was given
          #puts "  debug - inside IF2"
          ip.prepareOPLines(cur_range_firstdev_hex,cur_range_count)
        else # IF2 - more than one device were given
          #puts "  debug - inside IF2 else"
          is_firstdev = "no"
          prevdev_dec = curdev_dec
        end # IF2

  else # IF1 - it is not a firstdev
    #puts "  debug - inside IF1 else"
        nextdev_dec = prevdev_dec.to_i + 1
        nextdev_dec == curdev_dec ? ( cur_range_count+=1 ) : ( prev_range_count = cur_range_count; cur_range_count = 1; range_lastdev_hex = sprintf("%04X", prevdev_dec); pre_range_firstdev_hex = cur_range_firstdev_hex; cur_range_firstdev_hex = sprintf("%04X", curdev_dec))
    #puts "    debug - cur_range_count is #{cur_range_count}"

    if dev_count != total_devs # IF3 - more devices to follow
          #puts "  debug - inside IF3"
          if cur_range_count == 1 # IF4 - previous range finished, new range started - no else statement
            #puts "  debug - inside IF4"
            if prev_range_count > 1 # IF5 - previous device was part of a range
                  #puts "  debug - inside IF5"
                  ip.prepareOPLines(pre_range_firstdev_hex,prev_range_count,sprintf("%04X", prevdev_dec))
                  prev_range_count  = 0
                else # IF5 - previous device was standalone
                  #puts "  debug - inside IF5 - else"
                  ip.prepareOPLines(sprintf("%04X", prevdev_dec),1)
                end # IF5
          end #IF4 - no else statement
          prevdev_dec = curdev_dec
        else # IF3 - we've encountered last device
          #puts "  debug - inside IF3 - else"
          if cur_range_count == 1 # IF6 - last device encountered is a solo
            #puts "  debug - inside IF6"
            if prev_range_count > 1 # IF7 - previous device was part of a range
                  #puts "  debug - inside IF7"
                  ip.prepareOPLines(pre_range_firstdev_hex,prev_range_count,sprintf("%04X", prevdev_dec))
                else # IF7 - previous device was standalone
                  #puts "  debug - inside IF7 - else"
                  ip.prepareOPLines(pre_range_firstdev_hex,1)
                end # IF7
                ip.prepareOPLines(sprintf("%04X", curdev_dec),1)
          else # IF6 - last device is part of previous range
            #puts "  debug - inside IF6 - else"
        ip.prepareOPLines(cur_range_firstdev_hex,cur_range_count,sprintf("%04X", curdev_dec))
          end # IF6
        end # IF3
  end # IF1
end # end of iteration through ip.alldevs_dec_sorted array
ip.printOutput

## END OF SCRIPT

sanaswati
No comments yet.

Leave a Reply

*