我正在尝试解析HMMER给出的一些结果,并在tblout文件中能够隔离出我想要的匹配项。
尽管如此,如果仅与一个配置文件匹配,则同一值将重复多次。
例如,这是一次读取重复3次:
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
SRR6033660.1458607 FAM019859 2.5e-12 2.7e-12 55.0 54.9
SRR6033660.1458607 FAM015326 4e-14 4.2e-14 58.8 58.7
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
它可以匹配3个家庭,不过我只想选择e值最低的行(第3列和第4列)
我如何编写一个awk命令给我这个输出?
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
谢谢!
答案 0 :(得分:0)
通常无法选择两个字段的最小值,在这里我提出了一种线性组合,您可以在其中设置权重。
$ awk -v a=0.5 '{c=a*$3+(1-a)*$4}
!($1 in min) || c<min[$1]{min[$1]=c; minLine[$1]=$0}
END{for(k in minLine) print minLine[k]}' file | column -t
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
由于哈希,记录的顺序未保留。您可以添加序列号,然后根据该序列号进行排序。
答案 1 :(得分:0)
这将$3
和$4
相加,并且总和最小的具有最低的e值(在没有更好的定义的情况下):
$ awk '
# $3+$4==s[$1] { # this commented out part appends records when
# r[$1]=r[$1] ORS $0 # the sum of $3+$4 is equally small with the
# } # smallest so far
$3+$4<s[$1] || s[$1]=="" { # if the sum of $3+$4 is the smallest or first
s[$1]=$3+$4 # store the sum
r[$1]=$0 # and record
}
END { # after all records are processed
for(i in r) # loop thru stored records
print r[i] # and output them
}' file
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
如果取消注释第一个块,则脚本将输出所有具有最小$3+$4
的记录,例如:awk {script} file file
将输出:
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
SRR6033660.1458607 FAM000764 7.5e-25 8.1e-25 94.6 94.5
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
SRR6033660.161030 FAM007172 4e-15 4.2e-15 63.4 63.4
答案 2 :(得分:0)
其他人提供了纯awk解决方案。请注意,它们实际上涉及将数据的全部内容加载到内存中。在一般情况下,这是有问题的。
事实证明,这种类型(特别是GNU coreutils版本,不确定其他版本)足够聪明,可以在处理大量数据时使用临时文件。它还可以比较浮点中指定的数字。
所以:
LC_NUMERIC=C sort <TBLOUT -k1 -k3g -k4g | awk 't!=$1{t=$1;print}'
LC_NUMERIC=C
确保我们在数字写为1.234,56(而不是1,234.56)的语言环境中正确排序-k3g
和-k4g
之间切换