0

我想过滤一个文件,以便我可以获得在第 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,但都无济于事。任何帮助将非常感激。

4

2 回答 2

1

编辑:根据 OP,它应该是单读的,awk所以添加它 not.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
于 2018-07-10T08:46:43.390 回答
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。如果不是,请跟踪$1in的计数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

它本质上所做的是跟踪两个数组 (ab) 都由第一列索引。如果 arraya不包含 column 的元素,$2则将其添加到 string a[$1]。它还将整行存储在b[$1]分隔符中ORS。最后,我们计算 中有多少个字段a[i],如果是两个,则打印b[i]

于 2018-07-10T09:08:45.300 回答