AWK-根据分数选择要打印的行
我有一个标签分隔的文件,包含一系列带有相关分数的引理。 该文件包含5列,第一列是引理,第三列是包含分数的列。我需要做的是,当引理不重复时,按原样打印行,当引理重复时,打印分数最高的行 在 期望输出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
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;
}
}
结束{打印行;}
- 假设是:文件按引理排序
- 当引理改变时(或者在变量为空的最开始时),引理、分数和行被保存
- 当引理改变时(或在最后),将打印上一个引理的行
- 当当前行属于同一引理且分数较高时,值将再次保存
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。