使用awk提取具有不同类型的模式的特定“单词”(以及可能的重复条目),并创建一个新的制表符分隔文件

时间:2018-11-20 15:27:25

标签: awk fasta

我有许多fasta文件,必须从“标题”行中提取信息。

输入文件

>12321:Chr13 923456-923659(3C->A)|Chr14 463456-463669(4T->A)
AGCTAAAAAATGCGATG
>50:Chr1 495831-495959
TGCGATTATGCGATTATGCGAT
>5891:Chr13 363456-573659(3T->A)|Chr13 363456-573659(3T->A)|Chr14 463456-463669(4A->T)
AATATGCGATGAGCTAAG
>893:Chr21 139656-139690(3C->A)|Chr14 149656-149690(4T->A)
TGCTATGAGCTAATAAAAAATGCGATG

输出文件(这是预期的输出) 对于每行的每个Chr,我们都会获得坐标和“>”之后的数字,但是如果有可能重复(在同一行内),则必须将其排除。括号内的内容均不使用。

Chr13  923456 923659    12321
Chr14  463456 463669    12321
Chr1   495831 495959    50
Chr13  363456 573659    5891
Chr14  463456 463669    5891
Chr21  139656 139690    893
Chr14  149656 149690    893

我用过:

egrep ^[\>] file1.fas > file1_head.fas

仅提取标题行。 然后:

 awk -F: '/\>/ {n=split($2,s,"|");for(i=0; i<n; ++i) print $1 "\t" s[i] }' file1_head.fas > new.txt

当前输出:

>12321
>12321  Chr13 923456-923659(3C->A)
>50
>5891
>5891   Chr13 363456-573659(3T->A)
>5891   Chr13 363456-573659(3T->A)
>893
>893    Chr21 139656-139690(3C->A)
>353
>353    Chr13 363456-573659(3T->A)
>353    Chr13 363456-573659(3T->A)

问题:

  • 在某些行中,没有任何|可能导致输出的第一个问题(不打印第二列)
  • 如果重复/重复/ ...,我应该如何只保留一个条目?

我希望做的是为每个Chr *加上坐标和数字,以使文件格式类似于bed

提前谢谢

“真实”文件中的一部分:https://jpst.it/1tSMN

新示例

>25828:Chr15 99785054-99806017|Chr15 99785054-99806017|Chr15 101748003-101785983|Chr15 101748003-101785983|Chr15 101748003-101785983 
TCTGAGAAGATGAACTCCTTGGTCTGCCT 
>24578:Chr15 62204018-62281012|Chr15 62204018-62281012 
TTCAGTTTGAATCTAAGGAGCC 
>2439:Chr15 99785054-99806017|Chr15 99785054-99806017|Chr15 101748003-101785983 
TCTGAGAAGATGAACTCCTTGGTCTG
>1:KI270734.1 70016-79001(19T->C)
CGCGGGTGTATGCCAT
>2:GL000224.1 117026-129966(3T->G)
TCCCGAATCGGA

预期输出:

Chr15 99785054 99806017 25828 
Chr15 101748003 101785983 25828 
Chr15 62204018 62281012 24578 
Chr15 99785054 99806017 2439
Chr15 101748003 101785983 2439
KI270734.1 70016 79001 1
GL000224.1 117026 129966 2

2 个答案:

答案 0 :(得分:1)

EDIT2: 由于OP有时无法提供chr字符串,因此添加逻辑以获取任何类型的字符串输出。

awk -F"[:|]" '
/^>/ !e[$0]++{
  sub(/>/,"",$1)
  for(i=2;i<=NF;i++){
      num=split($i,array,"[- (]")
      if(!b[array[1]"("array[num-1]array[num]]++){
        print array[1],array[2],array[3],$1
      }
    delete array
  }
}'  Input_file


编辑: :由于OP询问完整的行可以重复,因此要照顾好这些行可以尝试遵循。

awk -F"[:|]" '
/^>/ !e[$0]++{
  sub(/>/,"",$1)
  for(i=2;i<=NF;i++){
    if($i ~ /Chr/){
      num=split($i,array,"[- (]")
      if(!b[array[1]"("array[num-1]array[num]]++){
        print array[1],array[2],array[3],$1
      }
    delete array
    }
  }
}'  Input_file


第一个解决方案: :考虑到您需要元素的索引,例如-> Chr13,(3C->A)等。 您能不能试一下。

awk -F"[:|]" '
/^>/{
  sub(/>/,"",$1)
  for(i=2;i<=NF;i++){
    if($i ~ /Chr/){
      num=split($i,array,"[- (]")
      if(!b[array[1]"("array[num-1]array[num]]++){
        print array[1],array[2],array[3],$1
      }
    delete array
    }
  }
}'    Input_file

输出如下。

Chr13 923456 923659 12321
Chr14 463456 463669 12321
Chr1 495831 495959 50
Chr13 363456 573659 5891
Chr14 463456 463669 5891
Chr21 139656 139690 893


第二个解决方法: 考虑到您需要索引例如-> Chr13,363456,573659,请执行以下十个操作。

awk -F"[>:|]" '                                      ##Setting field separator as either > or : or | for all lines for Input_file.
NF>1 && /^>/{                                        ##Checking condition if NF>1 and line starts from > then do following.
  for(i=3;i<=NF;i++){                                ##Starting a for loop from i=3 to value of NF in current line.
    if($i ~ /Chr/){                                  ##checking condition if field value is Chr string then only do further things.
      split($i,array,"[- (]")                        ##Using split function to split current field value into array named array and field separators as - or space or (
      val=array[1] OFS array[2] OFS array[3]         ##Creating variable val whose value is arrays 1,2 and 3 values with OFS values in between them.
      delete array                                   ##Deleting this array for safer side so it shouldnot print previous values wrongly.
    }
    if(!a[val]++ && val){                            ##For removing duplicates checking if array a index with val is there or not and val is NOT NULL then do following
      print val,$2                                   ##Printing variable val,$2 here.
    }
    val=""                                           ##Nullifying variable val here.
  }
}' Input_file                                        ##mentioning Input_file name here.

答案 1 :(得分:1)

awk -F':' '/>/{gsub(/\|/, RS NR FS $1 FS); print NR FS $0}' file1_head.fas | awk -F'[->:( ]' '{key = $1 FS $4 FS $5 FS $6}!s[key]{s[key] = 1; print $4, $5, $6, $3}'

返回:

Chr13 923456 923659 12321
Chr14 463456 463669 12321
Chr1 495831 495959 50
Chr13 363456 573659 5891
Chr14 463456 463669 5891
Chr21 139656 139690 893
Chr14 149656 149690 893

编辑:第二个示例:

返回:

Chr15 99785054 99806017 25828
Chr15 101748003 101785983 25828
Chr15 62204018 62281012 24578
Chr15 99785054 99806017 2439
Chr15 101748003 101785983 2439
KI270734.1 70016 79001 1
GL000224.1 117026 129966 2