我想过滤文件,以便获得与第1列匹配但与第2列不匹配的行。在以下示例中:
00b27c71-a833-4605-9fb3-a2714ac98092 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af75 ENST00000367142.4 8 60 0
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.5 130 12 4
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000367142.7 8 60 0
00d77e65-466e-4fe6-ad0f-bc6b3f44af74 ENST00000258424.2 8 60 0
我想在第1列中找到恰好出现两次但在第2列中不匹配的整体,即,应该忽略组合column1,column2中的重复项。因此,预期输出为:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
第3、4、5等栏中的内容对于过滤并不重要,但我确实需要保留信息。
我还需要从另一个输出中将其通过管道传递,这对于读取文件和保留标题是必需的。所以我需要以下格式的东西:
samtools view -h file.bam | code that I need > results.bam
我尝试了几种版本的awk,但无济于事。任何帮助将不胜感激。
答案 0 :(得分:1)
编辑: :根据OP,它应该是从awk
读取的单次读入,因此不能添加。w
your_command | awk '
{
a[$1]++;
b[$1 FS $2]++;
c[$1 FS $2]=$0
}
END{
for(i in a){
for(j in b){
split(j,array," ");
if(a[i]==2 && b[j]==1 && i==array[1]){ print c[j] }
}
}}'
能否请您尝试以下操作,如果有帮助,请告诉我。
awk 'FNR==NR{a[$1]++;b[$1 FS $2]++;next} a[$1]==2 && b[$1 FS $2]==1' Input_file Input_file
答案 1 :(得分:1)
我相信您的追求如下:
awk '!($1 FS $2 in a) { b[$1]++; a[$1 FS $2]=$0 }
END { for(i in a) {$0=i; if (b[$1]==2) print a[i] } }' file
这将输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
它的主要作用是检查组合$1 FS $2
是否在数组a
中。如果不是,请跟踪$1
中b[$1]
的计数,并将整行存储在a[$1 FS $2]
中。最后,如果计数正确,请打印a[i]
。请注意,b
的密钥是通过将密钥i
重新分配给$0
获得的。这将重新定义字段$1
和$2
,而$1
是您想要的键。
注意:由于数组遍历以未指定的顺序进行,因此上述脚本不一定跟踪该顺序。如果要保留订单,则需要跟踪行索引:
awk '!($1 FS $2 in a) { b[$1]++; a[$1 FS $2]=$0; c[NR]=$1 FS $2 }
END { for(i=1;i<=NR;++i) if(i in c) { $0=c[i]; if (b[$1]==2) print a[$0]}
}' file
输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
旧答案:
awk '!($1 in a) { a[$1]=$2; b[$1]=$0; next }
!match($2,a[$1]){a[$1]=a[$1] FS $2; b[$1]=b[$1] ORS $0}
END { for (i in a) if (gsub(FS,FS,a[i]) == 1) print b[i] }' file
这将输出:
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000258424.2 12 60 2048
00b27c71-a833-4605-9fb3-a2714ac98091 ENST00000352983.6 157 60 16
它本质上的作用是跟踪两个都由第一列索引的数组(a
和b
)。如果数组a
不包含列$2
的元素,则它将其添加到字符串a[$1]
中。它还将完整行存储在b[$1]
中,并以ORS
分隔。
最后,我们计算a[i]
中有多少个字段,如果为两个,则打印b[i]
。