AWK - 根据分数选择要打印的行

时间:2016-03-04 20:26:28

标签: awk gawk

我有一个制表符分隔文件,其中包含一系列带有相关分数的词条。 该文件包含5列,第一列是引理,第三列是包含分数的列。我需要做的是按原样打印直线,不重复引理,并在重复引理时打印得分最高的线。

function ColorChange(color) {
    if(color == "green"){
        color = "blue";
    }
    else if(color == "blue"){
        color = "red";
    }
    else{
        color = "green";
    }
    return color;
}

期望的输出

Lemma    ---    Score    ---    ---
cserép    06a    55    6    bueno
darázs    05     38    1    bueno
dél    06a    34    1    bueno
dér    06a    29    1    bueno
díj    05    14    89    malo
díj    06a    2    101    malo
díj    06b    2    101    malo
díj    07    90    13    bueno
díj    08a    2    101    malo
díj    08b    2    101    malo
egér    06a    66    5    bueno
fonal    05    12    1    bueno
fonal    07    52    4    bueno

我做了什么。但只有当引理重复一次时它才有效。

Lemma    ---    Score    ---    ---
cserép    06a    55    6    bueno
darázs    05    38    1    bueno
dél    06a    34    1    bueno
dér    06a    29    1    bueno
díj    07    90    13    bueno
egér    06a    66    5    bueno
fonal    07    52    4    malo

4 个答案:

答案 0 :(得分:2)

这个不要求文件按引理排序,但是,它会保留所有行在内存中打印(每个引理一行),因此可能不适合文件有数百万种不同的外表。

它也不尊重原始文件的顺序。

最后,它假设所有分数都是非负的!

$ cat lemma.awk
BEGIN { FS = OFS = "\t" }
NR == 1 { print }
NR > 1 {
    if ($3 > score[$1]) {
        score[$1] = $3
        line[$1] = $0
    }
}
END { for (lemma in line) print line[lemma] }


$ awk -f lemma.awk lemma.txt
Lemma   --- Score   --- ---
cserép  06a   55    6   bueno
díj     07    90    13  bueno
fonal   07    52    4   bueno
darázs  05    38    1   bueno
egér    06a   66    5   bueno
dél     06a   34    1   bueno
dér     06a   29    1   bueno

答案 1 :(得分:1)

使用gnu awk测试:

prevLemma != $1 {
          if( prevLemma ) {
            print line;
          }
          prevLemma = $1;
          prevScore = $3;
          line = $0;
        }
prevLemma == $1 { if( prevScore < $3 )  {
            prevScore = $3;
            line = $0;
          }
        }
END         { print line;}
  • 假设是:文件按引理排序
  • 当引理发生变化时(或者在变量为空的最开始时),引理,分数和线被保存
  • 当引理发生变化时(或在END中),打印前一个引理的行
  • 当当前行属于相同的引理且得分较高时,值会再次保存

答案 2 :(得分:1)

$ cat tst.awk
$1 != prev { printf "%s", maxLine; maxLine=""; max=$3; prev=$1 }
$3 >= max  { max=$3; maxLine=$0 ORS }
END  { printf "%s", maxLine }

$ awk -f tst.awk file
Lemma    ---    Score    ---    ---
cserép    06a    55    6    bueno
darázs    05     38    1    bueno
dél    06a    34    1    bueno
dér    06a    29    1    bueno
díj    07    90    13    bueno
egér    06a    66    5    bueno
fonal    07    52    4    bueno

答案 3 :(得分:-2)

使用脚本:

if ($1 != $5) print $0
else 
  {
  score($NR) = $3
  print $0
  }

实际上,使用perl可能会更好。