#!/usr/bin/env python import os import sys import string sys.path.insert(0,'/dcslib/allsys/packages/python/local-lib') sys.path.insert(0,'/usr/local/lib') sys.path.insert(0,os.path.expanduser('~/lib')) try: import modunits modunits_builtins = modunits.builtins() except: modunits_builtins = [] by=[] sep='\0' # this will rarely need to be changed dict={} sum=1 sumby=-1 total=0 percentages=0 units='' after_decimal = 1000 def usage(retval): sys.stderr.write('Usage: %s [-t] [-p] [-i separator] [-h] -b field1 -b field2 ... -b fieldn -s field\n' % sys.argv[0]) sys.stderr.write('-h\t\tsays to show this help message\n') sys.stderr.write('-t\t\tsays to give totals\n') sys.stderr.write('-p\t\tsays to give percentages\n') sys.stderr.write('-i separator\tsays to use separator internally for aggregating keys\n') sys.stderr.write('-b field\tindicates what fields to summarize by\n') sys.stderr.write('-s field\tindicates what field to add up\n') sys.stderr.write('-u units\tindicates what units to use, if any. Options are: %s\n' % string.join(modunits_builtins)) sys.stderr.write('-d digits\tindicates how many digits to put after the decimal point, at maximum\n') sys.exit(retval) while sys.argv[1:]: if sys.argv[1] == '-b' and sys.argv[2:]: by.append(string.atoi(sys.argv[2])) del sys.argv[1] elif sys.argv[1] == '-i' and sys.argv[2:]: sep=sys.argv[2] del sys.argv[1] elif sys.argv[1] == '-d' and sys.argv[2:]: after_decimal=string.atoi(sys.argv[2]) del sys.argv[1] elif sys.argv[1] == '-s' and sys.argv[2:]: sumby=string.atoi(sys.argv[2]) del sys.argv[1] elif sys.argv[1] == '-t': totals=1 elif sys.argv[1] == '-p': percentages=1 elif sys.argv[1] == '-h': usage(0) elif sys.argv[1] == '-u' and sys.argv[2:]: units=sys.argv[2] if not units in modunits_builtins: sys.stderr.write('Sorry, illegal units specified\n') usage(1) del sys.argv[1] else: usage(1) del sys.argv[1] if len(by) == 0: sys.stderr.write('Must specify at least one -b\n') usage(1) if sumby < 0: sys.stderr.write('Must specify a positive -s\n') usage(1) if totals == 0 and percentages == 0: sys.stderr.write('Must give one or both of -t or -p\n') usage(1) while 1: line = sys.stdin.readline() if not line: break fields=string.split(line) badline=0 for b in by: if not fields[b:]: badline=1 if not fields[sumby:]: badline=1 if badline: sys.stderr.write("Bad line: %s" % line) else: key = '' for b in by: if key == '': key = key + fields[b] else: key = key + sep + fields[b] if dict.has_key(key): try: dict[key] += string.atof(fields[sumby]) except: sys.stderr.write('Could not convert %s to a float\n' % fields[sumby]) else: dict[key] = sumby keys = dict.keys() keys.sort() #print len(keys) if totals: for key in keys: prefix=string.splitfields(key,sep) for p in prefix: sys.stdout.write(p+'\t') #sys.stdout.write(str(dict[key])+'\n') # give a pure number, whether the user requested it or not # (should be an option someday) if units == '': s = str(dict[key]) else: s = modunits.modunits(units,dict[key]) fields = string.splitfields(s,'.') sys.stderr.write('s is %s, fields is %s\n' % (s, str(fields))) len_fields = len(fields) if len_fields == 1: pass elif len_fields == 2: s = fields[0] + '.' + fields[1][0:after_decimal] else: sys.stderr.write('Internal error, too many fields from modunits\n') sys.stdout.write(s+'\n') def percent(numerator,denominator): perc = int(numerator*1000.0/denominator)/10.0 return perc if percentages: if totals: print total=0 # generate our total for key in keys: total+=dict[key] for key in keys: prefix=string.splitfields(key,sep) for p in prefix: sys.stdout.write(p+'\t') if total == 0: sys.stdout.write('INF\n') else: sys.stdout.write(str(percent(dict[key],total))+'%\n')