#!/usr/bin/gawk -f
# /* vim: set filetype=awk : */ -*- awk -*-
#
# ----| bars |--------------------------------------
#
# _ _ _ _ _ ((
# |=|=|=|=|=|.----------------------------. _))_
# |-|-|-|-|-|| a 'requirez' code bundle | ___\__/)_
# |_|_|_|_|_|'----------------------------'|_||_~~_|_|
#
# Built by "oelrawas" on Wed Nov 22 13:09:52 EST 2006.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# #---- [ranges.awk ] ------------------------------------------
function from(x,y,z) {
return (z >= x && z <= y) ? z : bad(z " not in [" x ".." y "]");
}
function round(x) {
return x<0 ? int(x-0.5) : int(x+0.5)
}
function between(min,max) {
return max==min ? min : min + ((max-min)*rand())
}
function most(x,y) { return x > y ? x : y }
function least(x,y) { return x < y ? x : y }
function within(min,max,bias) {
# pick a number between "min" and "max", with a little "bias"
return min + (max - min)*rand()^bias
# if bias = A >= 1 then mean = (max+min)*B is towards to "min" end
# BIAS mean
# ---- ----
# 1 0.5
# 2 0.33
# 3 0.25
# 4 0.2
# 5 0.17
# 6 0.14
# 7 0.13
# 8 0.11
# 9 0.10
# 10 0.09
# if bias = A < 1 then mean = (max+min)*B is towards the "max" end
# BIAS mean
# ---- ----
# 0.5 0.67
# 0.33 0.75
# 0.25 0.8
# 0.2 0.83
# 0.167 0.86
# 0.14 0.87
# 0.125 0.89
# 0.11 0.9
# 0.10 0.91
}
# #---- [hist.awk ] ------------------------------------------
BEGIN{
split("",Num,""); #array where we store the numbers
Inf= 2^32; #the largest number we can process
Max = -1*Inf; #max count seen in any bucket
#initialized to the smallest number
Here; #the key of the current bucket
Empty = 1; #false if some data seen
SumOfSquares[0] = 0; #initializes the array for sum of squares
Sums[0] = 0; #initializes the array for sums
STDEVColumnWidth = 0; #initializes the width of the STDEV column
MeanColumnWidth = 0; #initializes the width of the mean column
DefaultWidth = 7; #this is the default column width
}
NR==1{
if (Collect=="NF") Collect = NF;
#it finds the length of the column from the maximum digits needed
STDEVColumnWidth = Round ? round(log(Round)/log(10)) + 1 : DefaultWidth;
MeanColumnWidth = STDEVColumnWidth;
}
{
Empty = 0;
Here = Round ? round($Collect/Round) * Round : $Collect;
Num[Here]++;
Max = (Num[Here] > Max) ? Num[Here] : Max;
SumOfSquares[Here] = SumOfSquares[Here] + $Collect*$Collect;
Sums[Here] = Sums[Here] + $Collect;
#if the column is not wide enough, if uses the maximum number of digits
if (round(log($Collect)/log(10)) + 1 > MeanColumnWidth)
MeanColumnWidth = round(log($Collect)/log(10)) + 1;
}
END{
if (! Empty)
NoSort ? histogram(Num) : sortedgram(Num);
}
function histogram(a, i){
for (i in a) print bar(a, i);
}
function sortedgram(a, add, i, j, keys, n){
#Pre-sort the histogram and generated the bars in sorted order
for (i in a) {
if (Round) {
keys[j++] = i+0;} #ensures numeric, not string, sort
else keys[j++] = i;}
n = asort(keys);
for (i = 1; i <= n; i++)
print bar(a, keys[i]);
}
function bar(a, i, scale, stdev, mean){
#Genrate a single histogram bar of Marks, resized according to
#the BarColumnWidth.
scale = (Max < BarColumnWidth) ? 1 : BarColumnWidth/Max;
if (ShowMeanSTDEV){
#Calculates stdev from the SumOfSquares and Sums arrays.
if (a[i] > 1)
stdev=sqrt((SumOfSquares[i]-(Sums[i]^2)/a[i])/(a[i]-1))
else
stdev = 0;
#Calculates the mean from Sums array.
if (a[i] > 0)
mean = Sums[i]/a[i];
else
mean = Sums[i];
}
if (Round){
if (ShowMeanSTDEV){
return sprintf(" %" KeyColumnWidth ".0f|%"\
ValueColumnWidth "d| %"\
MeanColumnWidth + 3 ".2f| %"\
STDEVColumnWidth + 3 ".2f| %s",\
i, a[i], mean, stdev,\
str(round(a[i]*scale), Mark))}
else{
return sprintf(" %" KeyColumnWidth ".0f| %"\
ValueColumnWidth "d| %s",\
i, a[i], str(round(a[i]*scale), Mark))}
}
else{
if (ShowMeanSTDEV){
return sprintf(" %" KeyColumnWidth " s| %"\
ValueColumnWidth " d| %"\
MeanColumnWidth + 3 ".2f| %"\
STDEVColumnWidth + 3 ".2f| %s",\
i, a[i], mean, stdev,\
str(round(a[i]*scale), Mark))}
else{
return sprintf(" %" KeyColumnWidth " s| %"\
ValueColumnWidth " d| %s",\
i, a[i], str(round(a[i]*scale), Mark))}
}
}
# #---- [str.awk ] ------------------------------------------
#
Generate a string of characters
function str(n,c, x) {
while ((n--) > 0) x= x c;
return x;
}
# #---- [about.awk ] ------------------------------------------
# #---- [commandLine.awk ] ------------------------------------------
# #---- [copyleft.awk ] ------------------------------------------
function copyleft() {
about(Who,What,When,Why);
print "";
print "This program is free software; you can redistribute it and/or";
print "modify it under the terms of the GNU Lesser General Public";
print "License as published by the Free Software Foundation; version 2.1.";
print "";
print "This program is distributed in the hope that it will be useful"
print "but WITHOUT ANY WARRANTY; without even the implied warranty of";
print "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU";
print "Lesser General Public License for more details.";
print "";
print "You should have received a copy of the GNU Lesser General Public";
print "License along with this program; if not write to the Free Software";
print "Foundation Inc. 51 Franklin St Fifth Floor Boston MA 02110-1301 USA";
}
function about(who,what,when,why) {
print what " : " why;
print "Copyright " when " " who ;
}
##---- [prints.awk ] ------------------------------------------
function prints(a0,b0,c0,d0,e0,f0,g0,h0,i0,j0,k0,l0,m0,n0,o0,p0,q0,r0,s0,t0,u0,v0,w0,x0,y0,z0,\
a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1,\
a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,\
a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,o3,p3,q3,r3,s3,t3,u3,v3,w3,x3,y3,z3,\
a4,b4,c4,d4,e4,f4,g4,h4,i4,j4,k4,l4,m4,n4,o4,p4,q4,r4,s4,t4,u4,v4,w4,x4,y4,z4,\
a5,b5,c5,d5,e5,f5,g5,h5,i5,j5,k5,l5,m5,n5,o5,p5,q5,r5,s5,t5,u5,v5,w5,x5,y5,z5,\
a6,b6,c6,d6,e6,f6,g6,h6,i6,j6,k6,l6,m6,n6,o6,p6,q6,r6,s6,t6,u6,v6,w6,x6,y6,z6,\
a7,b7,c7,d7,e7,f7,g7,h7,i7,j7,k7,l7,m7,n7,o7,p7,q7,r7,s7,t7,u7,v7,w7,x7,y7,z7,\
a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,m8,n8,o8,p8,q8,r8,s8,t8,u8,v8,w8,x8,y8,z8,\
a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,m9,n9,o9,p9,q9,r9,s9,t9,u9,v9) {
prints26(a0,b0,c0,d0,e0,f0,g0,h0,i0,j0,k0,l0,m0,n0,o0,p0,q0,r0,s0,t0,u0,v0,w0,x0,y0,z0);
prints26(a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,o1,p1,q1,r1,s1,t1,u1,v1,w1,x1,y1,z1);
prints26(a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2);
prints26(a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,o3,p3,q3,r3,s3,t3,u3,v3,w3,x3,y3,z3);
prints26(a4,b4,c4,d4,e4,f4,g4,h4,i4,j4,k4,l4,m4,n4,o4,p4,q4,r4,s4,t4,u4,v4,w4,x4,y4,z4);
prints26(a5,b5,c5,d5,e5,f5,g5,h5,i5,j5,k5,l5,m5,n5,o5,p5,q5,r5,s5,t5,u5,v5,w5,x5,y5,z5);
prints26(a6,b6,c6,d6,e6,f6,g6,h6,i6,j6,k6,l6,m6,n6,o6,p6,q6,r6,s6,t6,u6,v6,w6,x6,y6,z6);
prints26(a7,b7,c7,d7,e7,f7,g7,h7,i7,j7,k7,l7,m7,n7,o7,p7,q7,r7,s7,t7,u7,v7,w7,x7,y7,z7);
prints26(a8,b8,c8,d8,e8,f8,g8,h8,i8,j8,k8,l8,m8,n8,o8,p8,q8,r8,s8,t8,u8,v8,w8,x8,y8,z8);
prints26(a9,b9,c9,d9,e9,f9,g9,h9,i9,j9,k9,l9,m9,n9,o9,p9,q9,r9,s9,t9,u9);
}
function prints26(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) {
if (a) {print prints1(a) } else {return 1};
if (b) {print prints1(b) } else {return 1};
if (c) {print prints1(c) } else {return 1};
if (d) {print prints1(d) } else {return 1};
if (e) {print prints1(e) } else {return 1};
if (f) {print prints1(f) } else {return 1};
if (g) {print prints1(g) } else {return 1};
if (h) {print prints1(h) } else {return 1};
if (i) {print prints1(i) } else {return 1};
if (j) {print prints1(j) } else {return 1};
if (k) {print prints1(k) } else {return 1};
if (l) {print prints1(l) } else {return 1};
if (m) {print prints1(m) } else {return 1};
if (n) {print prints1(n) } else {return 1};
if (o) {print prints1(o) } else {return 1};
if (p) {print prints1(p) } else {return 1};
if (q) {print prints1(q) } else {return 1};
if (r) {print prints1(r) } else {return 1};
if (s) {print prints1(s) } else {return 1};
if (t) {print prints1(t) } else {return 1};
if (u) {print prints1(u) } else {return 1};
if (v) {print prints1(v) } else {return 1};
if (w) {print prints1(w) } else {return 1};
if (x) {print prints1(x) } else {return 1};
if (y) {print prints1(y) } else {return 1};
if (z) {print prints1(z) } else {return 1};
}
function prints1(x) { # if starts with a " ", then indent this string
return x ~ /^ / ? " "x : x;
}
# #---- [getopt.awk ] ------------------------------------------
#!/usr/bin/gawk -f
# getopt --- do C library getopt(3) function in awk
# Author: arnold@gnu.ai.mit.edu (in the 1990s)
# (and the clearArgs() function was added at the suggestion of Mathew Hall
# Tue, 2 Aug 2005)
# Valid options are passed to a function opt(opts,opt,arg) which
# must be supplied outside this file. e.g.
#
# function opt(opts,flag,arg) { print opt "= [" arg "]" }
# USAGE:
# a call to "getOpts(String)" (e.g. getopts("ab:cd") )
# will lead to on call xoof opt for each valid argument
function getOpts(opts, debug, tmp) {
Optind = 1; # skip ARGV[0]
Opterr = debug; # default is to diagnose
while ((tmp = getopt(ARGC, ARGV, opts)) != -1)
set(tmp, Optarg);
clearARGV(debug);
}
# External variables:
# Optind -- index of ARGV for first non-option argument
# Optarg -- string value of argument to current option
# Opterr -- if non-zero, print our own diagnostic
# Optopt -- current option letter
# Returns
# -1 at end of options
# ? for unrecognized option
# a character representing the current option
function getopt(argc, argv, options, thisopt, i) {
if (length(options) == 0) # no options given
return -1;
if (argv[Optind] == "--") { # all done
Optind++;
_opti = 0;
return -1;
} else if (argv[Optind] !~ /^-[^: \t\n\f\r\v\b]/) {
_opti = 0;
return -1;
}
if (_opti == 0)
_opti = 2;
thisopt = substr(argv[Optind], _opti, 1);
Optopt = thisopt;
i = index(options, thisopt);
if (i == 0) {
if (Opterr)
printf("%c -- invalid option\n",
thisopt) > "/dev/stderr"
if (_opti >= length(argv[Optind])) {
Optind++;
_opti = 0;
} else
_opti++;
return "?";
}
if (substr(options, i + 1, 1) == ":") {
# get option argument
if (length(substr(argv[Optind], _opti + 1)) > 0)
Optarg = substr(argv[Optind], _opti + 1);
else
Optarg = argv[++Optind];
_opti = 0;
} else
Optarg = "";
if (_opti == 0 || _opti >= length(argv[Optind])) {
Optind++;
_opti = 0
} else
_opti++;
return thisopt;
}
function clearARGV(debug, i,n,tmp) {
for(i=0;i<=ARGC;i++)
if(i>=Optind ) {
tmp[++n]=ARGV[i];
if(debug && i!=ARGC) printf("\trest ARGV[%d] = <%s>\n",i, ARGV[i]);
} else {
if(debug) printf("\tused ARGV[%d] = <%s>\n",i, ARGV[i]);
}
split("",ARGV,"");
ARGC=0
for(i in tmp)
ARGV[++ARGC]=tmp[i];
}
# #---- [inits.awk ] ------------------------------------------
function inits(flags,str, argp,tmp,n,i,x) {
argps(argp,flags);
n=split(str,tmp," ");
while(i < n) {
i++;
x=tmp[i];
if (sub(/^-/,"",x)) {
if(argp[x]) {
set(x,tmp[i+1]); i++
} else { set(x) }
} else {bad("skipping " tmp[i-1] " " x)}
}
}
function argps(argp,flags, x,n,tmp,i) {
n=split(flags,tmp,"");
for(i=1;i<=n;i++)
if (tmp[i]==":")
argp[tmp[i-1]]=1
}
# #---- [bad.awk ] ------------------------------------------
#Stuff
function bad(str) {
print str >> "/dev/stderr";
fflush("/dev/stderr");
Errors++;
Patience--;
}
function imPatient() {
if (Patience<=0) {
print "Aborting" >> "/dev/stderr";
fflush("/dev/stderr");
exit 1 }
}
function badIf(check,txt) {
if (check) bad(txt); return check;
}
BEGIN { Who = "Tim Menzies";
What = "bars";
When = "2006";
How = "b:cd:hk:m:nst:v:w:";
Why = "show column data as histograms";
}
function usage() { about(Who,What,When,Why);
prints("Usage: "What" [FLAGS] FILE"," ",
"FILE is columns of data."," ",
" -b NUM width of bars; default=["BarColumnWidth"]",
" -c show copyright",
" -d CHAR field seperator",
" -h show help",
" -k NUM width of 'key' column;default=["KeyColumnWidth"]",
" -m CHAR character to draw one histogram dot; default=["Mark"]",
" -n no sorting of keys",
" -s provides mean and standard deviation of each bar",
" -t NUM target column; default=["Collect"]",
" -v NUM width of 'value' column; default=["ValueColumnWidth"]",
" -w NUM width of each data bin; default=["Round"]");
}
function defaults() {
NoSort = 0;
ShowMeanSTDEV = 0;
inits(How,"-b 20 -d , -k 4 -m * -t 2 -v 3 -w 10");
}
function set(x,y) {
if (x == "b") {return BarColumnWidth = y};
if (x == "c") {copyleft(); exit};
#if (x == "d") {return FS="," };
if (x == "d") {return FS = y};
if (x == "h") {usage(); exit};
if (x == "k") {return KeyColumnWidth = y};
if (x == "m") {return Mark = y};
if (x == "n") {return NoSort = 1};
if (x == "s") {return ShowMeanSTDEV = 1};
if (x == "t") {return Collect = y};
if (x == "v") {return ValueColumnWidth = y};
if (x == "w") {return Round = y};
bad(x "? usage: " What " " How); exit;
}
BEGIN {defaults(); getOpts(How) ; }