计算linux文件中的min,max,count

时间:2013-08-27 10:14:54

标签: linux shell

我在linux服务器上有一个文件,其中包含以下数据:

a   22
a   10
a   17
a   51
a   33
b   51
b   47
c   33

我想要一个shell脚本或linux命令来查找第1列中每个值的min,avg,90%,max和count。

示例:

for a min = 10, avg = 26, 90% = 33, max = 51, and count = 5.

3 个答案:

答案 0 :(得分:0)

对于以a开头的行,这里是awk脚本。

$ echo 'a 22
a 10
a 17
a 51
a 33
b 51
b 47
c 33' | awk 'BEGIN{n=0;s=0;};/^a/{n=n+1;s=s+$2;};END{print n;print s;print s/n;}'
5
133
26.6

答案 1 :(得分:0)

使用awk:

awk 'NR==1{min=$1} {sum+=$2; if(min>=$2) min=$2; if(max<$2) max=$2} 
     END{printf("max=%d,min=%d,count=%d,avg=%.2f\n", max, min, NR, (sum/NR))}' file
max=51,min=10,count=8,avg=33.00

修改

awk '$1 != v {
   if (NR>1)
      printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k));
   v=$1; 
   min=$2;
   k=sum=max=0
}
{
   k++;
   sum+=$2;
   if (min > $2)
      min=$2;
   if (max < $2)
      max=$2
}
END {
   printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k))
}' < <(sort -n -k1,2 f)

<强>输出:

For a max=51,min=10,count=5,avg=26.60
For b max=51,min=47,count=2,avg=49.00
For c max=33,min=33,count=1,avg=33.00

答案 2 :(得分:0)

这是一个使用gawk甚至达到百分之九十的版本。

百分位数的定义是由...给出的 维基百科并称为Nearest rank

可以找到功能轮次here

#!/bin/bash

gawk '
function round(x, ival, aval, fraction)
{
    ival = int(x)    # integer part, int() truncates

    # see if fractional part
    if (ival == x)   # no fraction
        return ival   # ensure no decimals

    if (x < 0) {
        aval = -x     # absolute value
        ival = int(aval)
        fraction = aval - ival
        if (fraction >= .5)
            return int(x) - 1   # -2.5 --> -3
        else
            return int(x)       # -2.3 --> -2
    } else {
        fraction = x - ival
        if (fraction >= .5)
            return ival + 1
        else
            return ival
    }
}
# the following block processes all the lines
# and populates counters and values
{
    if($1 in counters) {
        counters[$1]++;
    } else {
        counters[$1] = 1;
    }
    i = counters[$1];
    values[$1, i] = $2;
} END {
    for (c in counters) {
        delete tmp;
        min = values[c, 1];
        max = values[c, 1];
        sum = values[c, 1];
        tmp[1] = values[c, 1];
        for (i = 2; i <= counters[c]; i++) {
            if (values[c, i] < min) min = values[c, i];
            if (values[c, i] > max) max = values[c, i];
            sum += values[c, i];
            tmp[i] = values[c, i];
        }

        # The following 3 lines compute the percentile.
        n = asort(tmp, tmp_sorted);
        idx = round(0.9 * n + 0.5); # Nearest rank definition
        percentile = tmp_sorted[idx];

        # Output of the statistics for this group.  
        printf "for %s min = %d, avg = %f, 90 = %d,max = %d, count = %d\n", c, min, (sum / counters[c]), percentile, max, counters[c]; 
    }
}'

运行执行:

./stats.sh < input.txt

我假设上面的脚本名为stats.sh,输入保存在input.txt中。

输出结果为:

for a min = 10, avg = 26.600000, 90 = 51,max = 51, count = 5
for b min = 47, avg = 49.000000, 90 = 51,max = 51, count = 2
for c min = 33, avg = 33.000000, 90 = 33,max = 33, count = 1

这里的解释是:

计数器是一个关联数组,键是第1列中的值 并且值是每个输入中找到的值的数量 第1栏中的值。

值是二维的(value_in_column_one,counter_per_value) 使第一列中的值按值分组的所有值的数组。

在脚本结束时,最外面的循环遍历所有值 在第1列中找到。最里面的for循环分析所有属于的值 到第1列中的特定值,它计算所有静态。