我是这个网站的新手,并试图学习awk。我试图找到field3的最大值,按field1分组并打印所有具有最大值的字段。字段2包含时间,这意味着每个item1有96个field2,field3和field4
的值输入文件:(以逗号分隔)
item1,00:15,10,30
item2,00:45,20,45
item2,12:15,30,45
item1,00:30,20,56
item3,23:00,40,44
item1,12:45,50,55
item3,11:15,30,45
期望的输出:
item1,12:45,50,55
item2,12:15,30,45
item3,11:15,30,45
到目前为止我尝试了什么:
BEGIN{
FS=OFS=","}
{
if (a[$1]<$3){
a[$1]=$3}
}
END{
for (i in a ){
print i,a[i]
}
但这仅打印
item1,50
item2,30
item3,30
但我需要打印相应的field2和field4,其最大值如所需的输出所示。请帮忙。
答案 0 :(得分:3)
这里的问题是你没有存储整行,所以当你查看最终数据时,没有完整的数据要打印。
您需要做的是使用另一个数组,比如data[index]=full line
:
BEGIN{
FS=OFS=","}
{
if (a[$1]<$3){
a[$1]=$3
data[$1]=$0} # store it here!
}
END {
for (i in a )
print data[i] # print it here
}
或者作为一个单行:
$ awk 'BEGIN{FS=OFS=","} {if (a[$1]<$3) {a[$1]=$3; data[$1]=$0}} END{for (i in a) print data[i]}' file
item1,12:45,50,55
item2,12:15,30,45
item3,23:00,40,44
答案 1 :(得分:3)
在sort
命令的帮助下:
sort -t, -k1,1 -k3,3nr file | awk -F, '!seen[$1]++'
答案 2 :(得分:1)
要完成这项工作,你需要:
$ cat tst.awk
BEGIN { FS="," }
!($1 in max) {
max[$1] = $3
data[$1] = $0
keys[++numKeys] = $1
}
$3 > max[$1] {
max[$1] = $3
data[$1] = $0
}
END {
for (keyNr=1; keyNr<=numKeys; keyNr++) {
print data[keys[keyNr]]
}
}
$ awk -f tst.awk file
item1,12:45,50,55
item2,12:15,30,45
item3,23:00,40,44
在进行最小/最大计算时,您应始终使用读取的第一个值来设定最小值/最大值,而不是假设它始终小于或大于某个任意值(例如,如果您为零或零跳过上面的!($1 in max)
块。
打印输出时,您需要keys
数组来保留输入顺序。如果您使用in
代替,那么输出顺序将是随机的。
请注意,惯用的awk语法很简单:
<condition> { <action> }
不是C风格:
{ if ( <condition> ) { <action> } }