AWK - 根据分数打印 Select 行
AWK - Select lines to print according to score
我有一个制表符分隔的文件,其中包含一系列带有相关分数的引理。
该文件包含 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 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
我做了什么。但它只在引理重复一次时有效。
BEGIN {
OFS=FS="\t";
flag="";
}
{
id=;
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[]=line[]";"";"";"";";
}
END {
line=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]
}
}
使用脚本:
if ( != ) print [=10=]
else
{
score($NR) =
print [=10=]
}
实际上,使用 perl 可能会更好。
使用 gnu awk 测试:
prevLemma != {
if( prevLemma ) {
print line;
}
prevLemma = ;
prevScore = ;
line = [=10=];
}
prevLemma == { if( prevScore < ) {
prevScore = ;
line = [=10=];
}
}
END { print line;}
- 假设是:文件按引理排序
- 当引理改变时(或者在一开始var为空时)引理、分数和行被保存
- 当引理改变时(或在 END 中),打印前一个引理的行
- 当当前行属于同一个引理并且具有更高的分数时,再次保存值
这个不需要按引理对文件进行排序,但是,它会将所有要打印的行保留在内存中(每个引理一个)所以可能不会适用于具有数百万个不同引理的文件。
它也不尊重原始文件的顺序。
最后,假设所有分数都是非负的!
$ cat lemma.awk
BEGIN { FS = OFS = "\t" }
NR == 1 { print }
NR > 1 {
if ( > score[]) {
score[] =
line[] = [=10=]
}
}
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 tst.awk
!= prev { printf "%s", maxLine; maxLine=""; max=; prev= }
>= max { max=; maxLine=[=10=] 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
我有一个制表符分隔的文件,其中包含一系列带有相关分数的引理。 该文件包含 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 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
我做了什么。但它只在引理重复一次时有效。
BEGIN {
OFS=FS="\t";
flag="";
}
{
id=;
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[]=line[]";"";"";"";";
}
END {
line=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]
}
}
使用脚本:
if ( != ) print [=10=]
else
{
score($NR) =
print [=10=]
}
实际上,使用 perl 可能会更好。
使用 gnu awk 测试:
prevLemma != {
if( prevLemma ) {
print line;
}
prevLemma = ;
prevScore = ;
line = [=10=];
}
prevLemma == { if( prevScore < ) {
prevScore = ;
line = [=10=];
}
}
END { print line;}
- 假设是:文件按引理排序
- 当引理改变时(或者在一开始var为空时)引理、分数和行被保存
- 当引理改变时(或在 END 中),打印前一个引理的行
- 当当前行属于同一个引理并且具有更高的分数时,再次保存值
这个不需要按引理对文件进行排序,但是,它会将所有要打印的行保留在内存中(每个引理一个)所以可能不会适用于具有数百万个不同引理的文件。
它也不尊重原始文件的顺序。
最后,假设所有分数都是非负的!
$ cat lemma.awk
BEGIN { FS = OFS = "\t" }
NR == 1 { print }
NR > 1 {
if ( > score[]) {
score[] =
line[] = [=10=]
}
}
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 tst.awk
!= prev { printf "%s", maxLine; maxLine=""; max=; prev= }
>= max { max=; maxLine=[=10=] 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