使用awk计算最大值和最小值

10

如何从以下文件中找到以MATH开头的行的最大值和最小值a,b,c值?

TITLE     a       b       c
MATH      12.3    -0.42   5.5
ENGLISH   70.45   3.21    6.63
MATH      3.32    2.43    9.42
MATH      3.91    -1.56   7.22
ENGLISH   89.21   4.66    5.32

它不能只是一条命令行。必须使用BEGIN函数和END编写脚本文件。

当运行我的程序时,我得到了错误的最小值,并最终得到了一个字符串作为最大值。请帮帮我!

以下是我对列a的代码:

BEGIN { x=1 }
{
 if ($1 == "MATH") {
        min=max=$2;
        for ( i=0; i<=NF; i++) {
                min = (min < $i ? min : $i)
                max = (max > $i ? max : $i)
        }
 }

}

END { print "max a value is ", max, " min a value is ", min }

谢谢!


发布你的代码。没有代码很难说你做错了什么。 - FatalError
好的,我已经添加了我的代码。 - mika
请看我的示例,不要为所有匹配项运行循环。 - konsolebox
4个回答

9
这段代码可以演示你想要的概念:
awk '$1!="MATH"{next}1;!i++{min=$2;max=$2;}{for(j=2;j<=NF;++j){min=(min<$j)?min:$j;max=(max>$j)?max:$j}}END{printf "Max value is %.2f. Min value is %.2f.\n", max, min}' file

输出:

MATH      12.3    -0.42   5.5
MATH      3.32    2.43    9.42
MATH      3.91    -1.56   7.22
Max value is 12.30. Min value is -1.56.

移除1来抑制这些信息:

awk '$1!="MATH"{next};...

脚本版本:

#!/usr/bin/awk

$1 != "MATH" {
    # Move to next record if not about "MATH".
    next
}
!i++ {
    # Only does this on first match.
    min = $2; max = $2
}
{
    for (j = 2; j <= NF; ++j) {
        min = (min < $j) ? min : $j
        max = (max > $j) ? max : $j
    }
}
END {
    printf "Max value is %.2f. Min value is %.2f.\n", max, min
}

1
对我来说,阅读$1!="MATH"比阅读!($1=="MATH")更容易。 - Jotne
感谢回复,这正是我需要的答案。但是为什么在for循环中你使用j = 2而不是j = 0呢? - mika
j 是指向目标字段编号的指针,数字从字段号 2 ($2) 开始,而参考字符串(MATH 等)位于字段 1 ($1)。 - konsolebox

1

请看您的for循环

它从i=0开始,所以条件应该是

i<NF 

代替

i<= NF

尝试使用以下一行代码替换那一行代码...我希望您能找到您要寻找的内容。

for(i=0;i<NF;i++){

其余的看起来都很好……谢谢


1
在for循环中,变量i应该至少从2开始(第二个字段),而不是0,代表整行,并以NF结束。
BEGIN { x=1;min=2147483647;max=-2147483648}
{
 if ($1 == "MATH") {            
        for ( i=2; i<=NF; i++) {
                min = (min < $i ? min : $i)
                max = (max > $i ? max : $i)
        }
 }

}

END { print "max a value is ", max, " min a value is ", min }

运行命令:(testawk.script 为上述 awk 脚本文件名,test.data 为输入数据文件名)

cat test.data | awk -f testawk.script

输出:

最大 a 值为 12.30,最小 a 值为 -1.56


这也可以工作,但是你能更深入地解释一下为什么i = 2吗? - mika
@user2763235 因为数字字段是从第二个字段a开始的。这样清楚吗? - lulyon

-2

我现在手头上没有终端,但是类似以下的代码可以获取每行中最小的值。

cat YOURFILE | grep "^MATH" | cat test | \   
while read CMD; do
    A=`echo $CMD |  awk '{ print $2 }'`
    B=`echo $CMD |  awk '{ print $3 }'`
    C=`echo $CMD |  awk '{ print $4 }'`

   #IF Statement for comparing the three of them 
   #echo the smallest
done

抱歉格式混乱了。我现在意识到您可能只想使用awk。我的错误 @luluyon - CoderDake

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接