roll.sh - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
roll.sh (2051B)
---
1 #!/bin/sh
2 # rolling sum and percentage.
3 # input should be sorted descending by value.
4
5 # usage(argv0)
6 usage() {
7 printf "Usage: %s [-k columns] [-v value]\n" "$1" >&2
8 printf "Example: %s -k 3,4 -v 2" "$1 < input.tsv > output.tsv" >&2
9 exit 2
10 }
11
12 kflag=
13 kval='""'
14 vflag=
15 vval='2'
16 while getopts k:v: name
17 do
18 case $name in
19 k)
20 kflag=1
21 kval="$OPTARG"
22 ;; # key columns
23 v)
24 vflag=1
25 vval="$OPTARG"
26 ;; # value column
27 ?)
28 usage "$0"
29 ;;
30 esac
31 done
32
33 # create awk expression to evaluate and to make it configurable.
34 kexpr="$(printf '%s' "$kval" | sed -e 's@,@ @g' -e 's@\([0-9]\+\)@\$\1@g')"
35 vexpr="$(printf '%s' "$vval" | sed -e 's@\([0-9]\+\)@\$\1@g')"
36
37 # rolling sum, but ignoring values <= 0
38 LC_ALL=C awk '
39 BEGIN {
40 FS = OFS = "\t";
41 ORS = "";
42 i = 0;
43 kk = 0;
44 }
45 {
46 line[i] = $0;
47 i++;
48
49 # config key column(s), if non-empty then it is grouped.
50 k = '"$kexpr"';
51
52 # value field.
53 value = '"$vexpr"' + 0.0; # config value column.
54 if (value <= 0.0)
55 value = 0.0;
56
57 values[i] = value;
58 # total per group
59 if (k != "") {
60 gtotal[k] += (value+0.0);
61
62 keys[i] = k;
63 if (!ukeycount[k]) {
64 ukeycount[k] = 1;
65 uniqkeys[kk] = k;
66 kk++;
67 }
68 }
69
70 # total
71 total += (value+0.0);
72 }
73 END {
74 sum = 0.0;
75 for (j = 0; j < i; j++) {
76 l = line[j];
77
78 value = values[j];
79 sum += value;
80
81 print l;
82 print OFS;
83 printf("%.5f", sum);
84 print OFS;
85 if (total > 0)
86 printf("%.5f", ((sum / total)*100.0));
87
88 k = keys[j];
89 if (k != "") {
90 print "\t";
91 gs = gsum[k] + 0.0;
92 printf("%.5f", gs);
93 print OFS;
94 gt = gtotal[k] + 0.0;
95 # percentage of the whole group vs total.
96 if (gt > 0)
97 printf("%.5f", ((gt / total) * 100.0));
98 gsum[k] += value;
99 print OFS;
100 # percentage of the group total.
101 if (gt > 0)
102 printf("%.5f", ((value / gt) * 100.0));
103 }
104 print "\n";
105 }
106
107 # summary / totals (per group).
108 #for (j = 0; j < kk; j++) {
109 # k = uniqkeys[j];
110 # print k;
111 # print OFS;
112 # gt = gtotal[k] + 0.0;
113 # printf("%.5f", gt);
114 # print OFS;
115 # if (total > 0)
116 # printf("%.5f", ((gt / total) * 100.0));
117 # print "\n";
118 #}
119 }'