我有一个这样的数据:A校和B校每个班级的最高和最低期中成绩(班级没有显示)
#school highest lowest
schoolA 99 53
schoolA 95 66
schoolA 88 48
schoolB 94 55
schoolB 91 36我想像这样合并它:
schoolA 99 48
schoolB 94 36显示了每个学校的最大值和最小值。我尝试过这样的方法:
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")这段代码可以按第一列(学校)合并行吗?
发布于 2018-07-17 22:41:44
如果datamash没问题:
$ datamash -W -g1 max 2 min 3 < ip.txt
schoolA 99 48
schoolB 94 36-W使用空格作为第一个字段的delimiter-g1分组第二个字段的最大值和第三个字段的最小值--header-in选项忽略它发布于 2018-07-17 22:18:21
首先,我不认为你的(condition)?var=one:two是正确的。例如:
awk 'BEGIN{(3>5)?a=1:2;print a}'不输出任何内容。应该是这样写的:
$ awk 'BEGIN{a=(3>5)?1:2;print a}'
2你不需要,getline.
getline.school。这不是你想要的。对于你的问题,你可以这样写:
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发布于 2018-07-18 00:10:49
使用POSIX awk,您可以执行以下操作:
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}。)
https://stackoverflow.com/questions/51382843
复制相似问题