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

AWK-根据分数选择要打印的行,awk,gawk,Awk,Gawk,我有一个标签分隔的文件,包含一系列带有相关分数的引理。 该文件包含5列,第一列是引理,第三列是包含分数的列。我需要做的是,当引理不重复时,按原样打印行,当引理重复时,打印分数最高的行 在 期望输出 Lemma --- Score --- --- cserép 06a 55 6 bueno darázs 05 38 1 bueno dél 06a 34 1 bueno dér 06a 29

我有一个标签分隔的文件,包含一系列带有相关分数的引理。 该文件包含5列,第一列是引理,第三列是包含分数的列。我需要做的是,当引理不重复时,按原样打印行,当引理重复时,打印分数最高的行

期望输出

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
我所做的一切。但它只在引理重复一次时有效

BEGIN {
    OFS=FS="\t";
    flag="";
}
{
    id=$1;

    if (id != flag)
    {
        if (line != "")
        {   
            sub("^;","",line);

            z=split(line,A,";");
            if ((A[3] > A[8]) && (A[8] != ""))
            {
                print A[1]"\t"A[2]"\t"A[3]"\t"A[4]"\t"A[5];
            }
            else if ((A[8] > A[3]) && (A[8] != ""))
            {
                print A[6]"\t"A[7]"\t"A[8]"\t"A[9]"\t"A[10]
            }
            else
            {
                print A[1]"\t"A[2]"\t"A[3]"\t"A[4]"\t"A[5]; 
            }
        }

        delete line;
        flag=id;
    }
    line[$1]=line[$1]";"$2";"$3";"$4";"$5;
}
END {

    line=line ";"$1";"$2";"$3";"$4";"$5
    sub("^;","",line);

    z=split(line,A,";");
    if ((A[3] > A[8]) && (A[8] != ""))
    {
        print A[1]"\t"A[2]"\t"A[3]"\t"A[4]"\t"A[5];
    }
    else if ((A[8] > A[3]) && (A[8] != ""))
    {
        print A[6]"\t"A[7]"\t"A[8]"\t"A[9]"\t"A[10]
    }
    else
    {
        print A[1]"\t"A[2]"\t"A[3]"\t"A[4]"\t"A[5]
    }

}
使用脚本:

if ($1 != $5) print $0
else 
  {
  score($NR) = $3
  print $0
  }
实际上,使用perl可能会更好。

使用脚本:

if ($1 != $5) print $0
else 
  {
  score($NR) = $3
  print $0
  }
实际上,使用perl可能会更好。

使用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;}
prevLemma!=$1 {
if(前置引理){
打印线;
}
prevLemma=1美元;
积分=$3;
行=$0;
}
prevLemma=$1{if(prevScore<$3){
积分=$3;
行=$0;
}
}
结束{打印行;}
  • 假设是:文件按引理排序
  • 当引理改变时(或者在变量为空的最开始时),引理、分数和行被保存
  • 当引理改变时(或在最后),将打印上一个引理的行
  • 当当前行属于同一引理且分数较高时,值将再次保存
使用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;}
prevLemma!=$1 {
if(前置引理){
打印线;
}
prevLemma=1美元;
积分=$3;
行=$0;
}
prevLemma=$1{if(prevScore<$3){
积分=$3;
行=$0;
}
}
结束{打印行;}
  • 假设是:文件按引理排序
  • 当引理改变时(或者在变量为空的最开始时),引理、分数和行被保存
  • 当引理改变时(或在最后),将打印上一个引理的行
  • 当当前行属于同一引理且分数较高时,值将再次保存

这个函数不要求文件按引理排序,但它会将所有行打印在内存中(每个引理一行),因此可能不适合包含数百万个不同引理的文件

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

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

$ 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

这个函数不要求文件按引理排序,但它将所有要打印的行保留在内存中(每个引理对应一行),因此可能不适合包含数百万个不同引理的文件

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

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

$ 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

文件是按引理排序的,所以同一引理的所有行都在一个块中吗?文件是按引理排序的,所以同一引理的所有行都在一个块中吗?显然,我的逻辑非常复杂。我必须向你学习。你的解决方案非常有效!。在这里阅读和回答,我还在学习如何有效地应用awk。您不需要测试
prevLemma==$1
,因为您之前只设置了几行
prevLemma=$1
。你不需要所有的尾随分号。您不应该单独测试
prevlema
,因为如果它的数值计算为零,则会失败-您可以测试
prevlema=“”
NR>1
。显然,我的逻辑非常复杂。我必须向你学习。你的解决方案非常有效!。在这里阅读和回答,我还在学习如何有效地应用awk。您不需要测试
prevLemma==$1
,因为您之前只设置了几行
prevLemma=$1
。你不需要所有的尾随分号。您不应该单独测试
prevlema
,因为如果它的数值计算为零,则会失败-您可以测试
prevlema=“”
NR>1
。这就是为什么每次lemma更改时,我的脚本都会删除数组。我喜欢你的解决方案,这就是为什么每次引理改变时我的脚本都会删除数组。我喜欢你的解决方案,因为perl内置了排序功能,使用awk你必须编写一个例程,在这种情况下非常简单。gnu awk内置了排序功能,你不需要/不需要排序。perl内置了排序功能,使用awk你必须编写一个例程,在这种情况下非常简单。gnu awk内置了sort,您无论如何都不需要/不需要sort。