【问题标题】:Minimum, Average and Maximum in columns列中的最小值、平均值和最大值
【发布时间】:2012-02-07 12:09:09
【问题描述】:

我有下一个问题,我想要两个最小值,一个最大值和这个输入的平均值:

 Call 1 1.160 ms
 Call 2 0.163 ms
 Call 3 1.154 ms
 Call 4 1.029 ms
 Call 5 0.291 ms
 Call 6 1.186 ms
 Call 7 1.089 ms
 Call 8 1.122 ms
 Call 9 0.975 ms
 Call 10 1.224 ms
 Call 11 0.965 ms
 Call 12 1.047 ms
 Call 13 1.138 ms
 Call 14 1.217 ms
 Call 15 1.189 ms
 Call 16 1.115 ms
 Call 17 0.950 ms
 Call 18 1.112 ms
 Call 19 1.227 ms
 Call 20 1.071 ms
 Call 21 1.108 ms
 Call 22 1.191 ms
 Call 23 1.139 ms
 Call 24 1.032 ms
 Call 25 1.305 ms
 Call 26 1.085 ms
 Call 27 1.404 ms
 Call 28 1.282 ms
 Call 29 1.031 ms
 Call 30 1.018 ms
 Call 31 1.308 ms
 Call 32 1.299 ms
 Call 33 1.096 ms
 Call 34 1.129 ms
 Call 35 1.271 ms
 Call 36 1.035 ms
 Call 37 1.238 ms
 Call 38 1.150 ms
 Call 39 1.042 ms
 Call 40 0.948 ms

我一直在使用这些命令:

 awk 'min=="" || $3 < min {min=$3; minline=$0}; END{ print minline}'

 awk '{ if ($3>max) {max=$3; line=$0} } END {print line }'

 awk '{s+=$3} END{print "Number of Calls: "NR, "\nAverage: "s/(NR)}'

输出是这样的:

 Minimun: Call 18 0.212 ms
 Maximun: Call 27 1.404 ms
 Number of Calls: 40
 Average: 1.1071

但我需要有 2 个最小值,其中一个显示在上面,但另一个应该是大于 0.800 的任何数字。我正在尝试这个:

 awk 'min=="0.800" || $3 < min {min=$3; minline=$0}; END{ print minline}'

但它什么也没显示。拜托,我需要您的帮助才能将其放入脚本中。

提前感谢您的帮助

【问题讨论】:

  • “另一个应该是大于 0.800 的任何数字。”请解释一下。为什么会是一分钟?
  • 这很难解释,对我来说也是一个要求..
  • 如果是“任意数”,最大数也是一个数>0.800,取那个即可。

标签: linux bash awk gawk


【解决方案1】:
kent$  awk 'BEGIN{min=999}
{a[NR]=$0;if($3<min){min=$3;m[1]=NR;}if($3>max){max=$3;m[2]=NR;}m[3]+=$3;}
END{print "Min:"a[m[1]];
        print "Max:"a[m[2]];
        print "Number Of Calls:" NR;
        print "Avg:"m[3]/NR;
        t=max>0.800?a[m[2]]:"None";
        print "Any greater than 0.800:"t}' yourFile

输出:

Min:Call 2 0.163 ms
Max:Call 27 1.404 ms
Number Of Calls:40
Avg:1.08837
Any greater than 0.800:Call 27 1.404 ms

注意:对于“任何大于 0.800 的数字”,我只是检查了 Max,如果 >0.800,则将其打印为幻数。如果没有,打印无。

编辑

对 OP 评论的更改:

kent$  awk 'BEGIN{min=mag=999}
{a[NR]=$0;if($3<min){min=$3;m[1]=NR;}if($3>max){max=$3;m[2]=NR;}if($3>0.800&&$3<mag){mag=$3;m[4]=NR} m[3]+=$3;}
END{print "Min:"a[m[1]];
        print "Max:"a[m[2]];
        print "Number Of Calls:" NR;
        print "Avg:"m[3]/NR;
        print "Any greater than 0.800:"a[m[4]]}' yourFile

输出:

Min:Call 2 0.163 ms
Max:Call 27 1.404 ms
Number Of Calls:40
Avg:1.08837
Any greater than 0.800:Call 40 0.948 ms

【讨论】:

  • 这真的很棒,抱歉没有具体说明,但您能否修复您的脚本以获得大于 0.800 的最小值?
  • @Martin_911 见答案编辑
  • 非常感谢,非常感谢您的帮助!
【解决方案2】:

你想要两个最小值:

awk '{ if (min1==""||$3<=min1) { min2=min1; line2=line1; min1=$3; line1=$0; }
       else if (min2=="" || $3 <= min2)                { min2=$3; line2=$0; } }
       END{ print line1; print line2}'

输出:

Call 2 0.163 ms
Call 5 0.291 ms

您希望最小值和第二个最小值大于 0.8 毫秒:

awk '{ if (min1==""||$3<=min1) { if(min1>0.8) {min2=min1; line2=line1;} min1=$3; line1=$0; }
       else if ($3>0.8 && (min2=="" || $3 <= min2))                   { min2=$3; line2=$0; } }
       END{ print line1; print line2}'

输出:

 Call 2 0.163 ms
 Call 40 0.948 ms

【讨论】:

  • 对不起我的无知,但你在哪里声明第一次应该是最小值,另一个应该大于 0.800?
  • 实际上输出应该是这样的: 最小:调用 18 0.212 毫秒 最小调用大于 0.800:调用 17 0.950 毫秒 最大:调用 27 1.404 毫秒 调用次数:40 平均:1.1071
  • 非常感谢。请让我编辑输入并使用您的脚本再试一次好吗?
  • 我已经做到了,你可以看到 Call 2 是 0.163,Call 5 是 0.291 ms。当我运行你的脚本(使用新输入)时,它会显示 Call 2 0.163 和 Call 5 0.291
  • 好的,我明白了。我怎么没看到。我测试了这个案例......好的,我正在修复它;-)
【解决方案3】:

解决方案 1

这是我在 Perl 中的解决方案,我是新手,但想学习:

#!/usr/bin/perl -n

BEGIN { $min1 = 9999; $min2 = 9999; $max = -1; }

($label, $callNumber, $callTime, $ms) = split;

$sum += $callTime;
if ($max < $callTime) {
    $max = $callTime;
    $maxLine = $_; 
}   

if ($min1 > $callTime) {
    $min1 = $callTime;
    $min1Line = $_; 
}   

if ($min2 > $callTime && $min1 != $callTime) {
    $min2 = $callTime;
    $min2Line = $_; 
}   

END {
    $average = $sum / $.; 
    print "Minimum1:        $min1Line";
    print "Minimum2:        $min2Line";
    print "Maximum:         $maxLine";
    print "Number of Calls: $.\n";
    print "Average:         $average\n";
}   

唯一棘手的部分是计算 $min2,它是次最小值。我的脚本看起来很长,但我相信它比其他一些解决方案更容易理解和维护。

解决方案 2

这个方案只计算了两个min,一个max,但是比较短:

sort -k 3,3 -n data.txt | sed -n '1,2s/^/Min: /p;$s/^/Max: /p'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 2017-12-15
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多