-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathavg
executable file
·112 lines (98 loc) · 2.12 KB
/
avg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/perl -nlw
use Getopt::Std;
BEGIN {
@data = ();
getopts('f:k:g:e:hv');
# used $opt_h twice to hack around spurious "used only once" warning
if ($opt_h and $opt_h) {
print "avg [-v] -g <line filter> -k <field> -e <convert field> -f <field filter>";
exit 1;
}
# prevent Name "main::opt_v" used only once: possible typo
$opt_v = $opt_v;
}
if (not defined $opt_g or /$opt_g/o) {
if (defined $opt_k) {
@_ = split;
$_ = $_[$opt_k - 1];
}
if (defined $opt_e) {
eval($opt_e);
}
push @data, $_;
}
sub avg {
my $sum = 0;
$sum += $_ for @_;
return format_num($sum / @_);
}
sub avg_p90 {
use integer;
my @args = (@_);
my $ndrop = (scalar @args) / 20;
if ($ndrop) {
splice @args, 0, $ndrop;
splice @args, -$ndrop;
}
return format_num(avg(@args));
}
sub stddev {
my $avg = avg(@_);
my $sum_mean_diff_sq = 0;
for (@_) {
my $diff = $_ - $avg;
$sum_mean_diff_sq += $diff ** 2;
}
return format_num(sqrt($sum_mean_diff_sq / scalar @_));
}
sub sum {
my $sum = 0;
$sum += $_ for @_;
return $sum;
}
sub format_num {
if ($_[0] < 9999) {
$_[0] = sprintf "%.2f", $_[0];
} elsif ($_[0] < 99999) {
$_[0] = sprintf "%.1f", $_[0];
} else {
$_[0] = sprintf "%d", $_[0];
}
}
sub i {
sprintf "%d", $_[0];
}
END {
my $count = scalar @data;
if ($count == 0) {
exit 0;
}
if ($opt_f) {
@data = grep { eval($opt_f) } @data;
}
@data = sort { $a <=> $b } @data;
if ($opt_v) {
printf "$_\n" for @data;
}
my @fields = (
'COUNT', sub { i(scalar @_) },
'AVG', \&avg,
'P90', \&avg_p90,
'MEDIAN', sub { i($_[@_/2]) },
'MIN', sub { i($_[0]) },
'MAX', sub { i($_[$#_]) },
'STDDEV', \&stddev,
'SUM', \&sum,
);
if ($opt_f) {
unshift @fields, 'TOTAL', sub { $count };
}
my $i = 0;
my @values = map { &$_(@data) } grep { $i++ % 2 } @fields;
my @len = map { length } @values;
my $format = '';
$format .= '%' . ($_ > 7 ? 16 : 8) . 's' for @len;
$i = 0;
printf $format . "\n", grep { ++$i % 2 } @fields;
printf $format . "\n", @values;
}