首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Awk查找每个键的最大值和最小值

Awk查找每个键的最大值和最小值
EN

Stack Overflow用户
提问于 2018-07-17 21:37:50
回答 4查看 599关注 0票数 0

我有一个这样的数据:A校和B校每个班级的最高和最低期中成绩(班级没有显示)

代码语言:javascript
复制
#school   highest  lowest
schoolA   99       53
schoolA   95       66
schoolA   88       48
schoolB   94       55
schoolB   91       36

我想像这样合并它:

代码语言:javascript
复制
schoolA   99       48
schoolB   94       36

显示了每个学校的最大值和最小值。我尝试过这样的方法:

代码语言:javascript
复制
awk '
BEGIN{getline;min=$3;max=$2} 
{($3<min)?min=$3:"";($2>max)?max=$2:""} 
END{OFS="\t";print $1,max,min}
'

它起作用了;然而,它有时会自动在min处加1分(第三列)

谁能教我如何正确地做这件事,并稍微解释一下上面的代码是什么意思?(特别是"getline")这段代码可以按第一列(学校)合并行吗?

EN

回答 4

Stack Overflow用户

发布于 2018-07-17 22:41:44

如果datamash没问题:

代码语言:javascript
复制
$ datamash -W -g1 max 2 min 3 < ip.txt 
schoolA 99  48
schoolB 94  36

  • -W使用空格作为第一个字段的delimiter
  • -g1分组第二个字段的最大值和第三个字段的最小值
  • 如果输入文件包括标题行,请使用--header-in选项忽略它
票数 4
EN

Stack Overflow用户

发布于 2018-07-17 22:18:21

首先,我不认为你的(condition)?var=one:two是正确的。例如:

代码语言:javascript
复制
awk 'BEGIN{(3>5)?a=1:2;print a}'

不输出任何内容。应该是这样写的:

代码语言:javascript
复制
$ awk 'BEGIN{a=(3>5)?1:2;print a}' 
2

你不需要,getline.

  • You,没有检查,
  • ,因此,你的代码会从所有学校的值中找到最小/最大值。,getline.
  • You,,
    • school。这不是你想要的。

对于你的问题,你可以这样写:

代码语言:javascript
复制
awk -v OFS='\t' '$1 in min{min[$1]=$3<min[$1]?$3:min[$1]
               max[$1]=$2>max[$1]?$2:max[$1]
               next } {min[$1]=$3;max[$1]=$2}
            END{for(x in min)print x, max[x], min[x]}' file
票数 0
EN

Stack Overflow用户

发布于 2018-07-18 00:10:49

使用POSIX awk,您可以执行以下操作:

代码语言:javascript
复制
awk ' BEGIN{fmt="%-15s%-10s%-10s\n"; printf fmt,"School","max","min"}
      !($1 in sch) {idx[++i]=$1; sch[$1]; arr[$1,"min"]=100}
      $2>arr[$1,"max"]{arr[$1,"max"]=$2}
      $3<arr[$1,"min"]{arr[$1,"min"]=$3}
      END{for (e=1;e<=length(idx);e++) printf fmt,idx[e],arr[idx[e],"max"],arr[idx[e],"min"]}' file
School         max       min       
schoolA        99        48        
schoolB        94        36      

正如所写的那样,这为打印的学校维护了文件顺序。如果您不关心输出顺序,那么编写起来会更简单。

不清楚你的文件是否有头文件。

如果有页眉,请用FNR==1{printf fmt,$1,$2,$3}替换printf fmt,"School","max","min"以打印页眉。(如果要跳过标题,则为FNR==1{next}。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51382843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档