首页 > 解决方案 > 哇;当两个文件共享一个公共标题时从两个文件中获取多行

问题描述

我有一个与有关该主题的许多其他问题非常相似的问题,但我无法将这些解决方案扩展到我正在寻找的确切输出。

我有两个以 fastq 样式格式化的文件,如下所示:

文件1.txt

@header:with:id:number:0001 1:this:number:indicates:pair:number
ABCD
+
1324
@header:with:id:number:0001 2:this:number:indicates:pair:number
EFGH
+
5678
@header:with:id:number:0002 2:this:number:indicates:pair:number
PQRS
+
9012
@header:with:id:number:0003 1:this:number:indicates:pair:number
IJKL
+
3456
@header:with:id:number:0003 2:this:number:indicates:pair:number
MNOP
+
7890

文件2.txt

@header:with:id:number:0004 1:this:number:indicates:pair:number
QRST
+
1324
@header:with:id:number:0004 2:this:number:indicates:pair:number
UVWX
+
5678
@header:with:id:number:0005 1:this:number:indicates:pair:number
CDEF
+
3456
@header:with:id:number:0005 2:this:number:indicates:pair:number
GHIJ
+
7890
@header:with:id:number:0002 1:this:number:indicates:pair:number
YZAB
+
9012

每个'块'有四行,第一行(标题)总是以@开头,并包括一个id号(例如0001)和一个索引(即'空格'后面的1或2)。每个 id 编号应该在具有两个索引的同一个文件中出现两次(就像上面示例中除 0002 之外的所有 id 编号一样)。现在我想分别存储 id-number 出现在两个文件中的块(表示在两个文件中只出现一次的块)。

在这种情况下,输出应该是:

@header:with:id:number:0002 1:this:number:indicates:pair:number
PQRS
+
9012
@header:with:id:number:0002 2:this:number:indicates:pair:number
YZAB
+
9012

并且这些行应该从原始文件中删除。

为此,到目前为止,我已将 awk 与以下命令一起使用

awk -F" " '/^@/ && NR==FNR {lines[$1]; next}
    $1 in lines {x=NR+3}
    (NR<=x) {print $0}' file2.txt file1.txt

这输出:

@header:with:id:number:0002 2:this:number:indicates:pair:number
PQRS
+
9012

那里的一半。

我的问题是,如何在两个文件中出现的标题中搜索 id 号,将它们存储在第三个文件中并从两个原始文件中删除相应的块?

标签: awkfastq

解决方案


您能否尝试使用显示的示例进行以下、编写和测试,应该可以在任何awk我相信的情况下工作,但只能在 GNU 中进行测试awk

awk '
FNR==NR{
  if($0~/^@/){
    match($0,/^@header:with:id:number:[0-9]{4}/)
    mat1=substr($0,RSTART,RLENGTH)
    arr1[mat1]++
  }
    val1[mat1]=(val1[mat1]?val1[mat1] ORS:"")$0
    next
}
{
  if($0~/^@/){
    match($0,/^@header:with:id:number:[0-9]{4}/)
    mat2=substr($0,RSTART,RLENGTH)
    arr2[mat2]++
  }
  val2[mat2]=(val2[mat2]?val2[mat2] ORS:"")$0
}
END{
  for(key1 in arr1){
    if(arr1[key1]==1 && arr2[key1]==1){print val1[key1] ORS val2[key1] }
  }
}' file1.txt file2.txt 

这将在两个文件中强制查找匹配索引的计数1,以防您希望1在任何一个文件中都有计数,然后更改arr1[key1]==1 && arr2[key1]==1arr1[key2]==1上述条件。

输出将如下所示,示例如下。

@header:with:id:number:0002 2:this:number:indicates:pair:number
PQRS
+
9012
@header:with:id:number:0002 1:this:number:indicates:pair:number
YZAB
+
9012

推荐阅读