我有以下文件
> head map.stats
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
ID=NbD053287.1.mrna1;Name=NbD053287.1;Parent=NbD053287.1.path1;coverage=100.0;identity=94.1;matches=738;mismatches=0;indels=46;unknowns=0
ID=NbD053281.1.mrna1;Name=NbD053281.1;Parent=NbD053281.1.path1;coverage=99.3;identity=99.1;matches=1476;mismatches=14;indels=0;unknowns=0
我想过滤掉$identity >= 95 && $coverage == 100
这样我就可以得到这个输出
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
我尝试过grep -oP '(?<=identity=).*?(?=;)' map.stats | awk '$1 >= 99'
,但并没有让我走得太远。怎么可能进行这种过滤呢?
提前谢谢你
答案1
这是另一种方法:
$ awk -F'[;=]' '$10>=95 && $8 == 100' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
技巧是将字段分隔符设置为;
or =
(这就是-F'[;=]'
作用)。那么, 的值identity
将是第 10 个字段, 的值coverage
将是第 8 个字段。由于awk
当表达式计算结果为 true 时 的默认操作是打印当前行,这意味着$10>=95 && $8 == 100
将打印与这两个条件匹配的任何行。
实际上,您也可以使用 GNU 执行此操作grep
,但您不需要该-o
选项,因为您需要整行,并且没有理由使用后向查找。您所需要的只是定义范围。由于您需要从95
到100
( >=95
) 的值,这意味着您需要 a后跟和9
之间的任意一个数字,或者 a :5
9
100
$ grep -P 'coverage=100.0.*identity=(9[5..9]|100)' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
请注意,我假设同一性不能采用大于 100 的值,这似乎是一个安全的假设,因为您可能正在考虑序列守恒,并且您无法获得比 100% 相同更相似的结果。
答案2
首先让我们使用将字段转换为数字
awk -F= 'NR==1 { for(i=1;i<=NF;i++) printf "%2d %s\n",i,$i ;}' file
1 ID
2 NbD053289.1.mrna1;Name
3 NbD053289.1;Parent
4 NbD053289.1.path1;coverage
5 100.0;identity
6 100.0;matches
7 702;mismatches
8 0;indels
9 0;unknowns
10 0
所以覆盖范围是 5,身份是 6
接下来,我们不能直接使用 awk,==
因为它会匹配字符串,所以我们使用 +1 转换为数字。
这个产量
awk -F= '$6+1>96 && ($5+1) == 101' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
在哪里
-F=
告诉 awk 用作=
分隔符$6+1>96
如上所述转换为数字并过滤