#!/usr/bin/env ruby
USAGE = <<-EOF
`num`: Extract numbers from formatted ASCII text by context.

XXX very unfinished

Example:

    kragen@VOSTRO9:~/devel/misc$ df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda1              7012744   6377232    279276  96% /
    tmpfs                   508696         0    508696   0% /lib/init/rw
    varrun                  508696       136    508560   1% /var/run
    varlock                 508696         0    508696   0% /var/lock
    udev                    508696       156    508540   1% /dev
    tmpfs                   508696      1548    507148   1% /dev/shm
    lrm                     508696      2192    506504   1% /lib/modules/2.6.28-19-generic/volatile
    /dev/sdb1             15637568  13398528   2239040  86% /media/disk
    kragen@VOSTRO9:~/devel/misc$ df -k | num sda1
    sda1
    7012744
    kragen@VOSTRO9:~/devel/misc$ df -k | num -4 sda1   # fourth number after
    sda1
    96
    kragen@VOSTRO9:~/devel/misc$ df -k | num +1 '% /'  # first number before (first occurrence of)
    % /
    96
    kragen@VOSTRO9:~/devel/misc$ df -k | num +1 /var/run
    /var/run
    1
    kragen@VOSTRO9:~/devel/misc$ df -k | num +2 /var/run # second number before
    /var/run
    508560
    kragen@VOSTRO9:~/devel/misc$ sensors
    acpitz-virtual-0
    Adapter: Virtual device
    temp1:       +42.0°C  (crit = +102.0°C)                  
    kragen@VOSTRO9:~/devel/misc$ sensors | num temp1
    temp1
    +42.0

Multiple field selectors extract multiple fields.  -q suppresses the
headers; -h 'headername' allows you to give a different title:

    kragen@VOSTRO9:~/devel/misc$ df -k | num -h 'root' +1 '% /'
    root
    96
    kragen@VOSTRO9:~/devel/misc$ ifconfig eth1
    eth1      Link encap:Ethernet  HWaddr (censored)
              inet6 addr: fe80::(censored)/64 Scope:Link
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:696140 errors:0 dropped:0 overruns:0 frame:534861
              TX packets:383282 errors:22 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:1022490557 (1.0 GB)  TX bytes:31222411 (31.2 MB)
              Interrupt:17 
    kragen@VOSTRO9:~/devel/misc$ ifconfig eth1 | num -t rxbytes 'RX bytes'
    rxbytes
    1022490557
    kragen@VOSTRO9:~/devel/misc$ ifconfig eth1 | num -q 'RX bytes'
    1022490557
    kragen@VOSTRO9:~/devel/misc$ ifconfig eth1 | num -t rxbytes 'RX bytes' -t rxpackets 'RX packets'
    rxbytes     rxpackets
    1022490557  696140

XXX why doesn’t this work?

$ free | ./num cache
cache

$

EOF

# TODO:
# - handle multiple headers
# - handle “nth number after”
# - handle numbers before instead of after
# - make headers case-insensitive by default

args = ARGV
quiet = (args[0] == '-q')
args = args.drop(1) if quiet

pattern = Regexp.new(Regexp.escape(args[0]))
number = /[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?/

puts args[0] unless quiet
STDIN.each do |line|
  if m = line.match(pattern)
    puts number.match(line[m.end(0)..-1]).to_s
    break
  end  
end
