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

使用awk提取特定的“;字;使用不同类型的模式(以及可能的重复条目),并创建一个新的以制表符分隔的文件,awk,fasta,Awk,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-463

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

输入文件

>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
问题:

  • 在某些行中,没有任何|,这可能导致输出出现第一个问题(不打印第二列)
  • 如果是重复/三次/我应该如何只保留一个条目
我希望做的是为每个Chr*加上坐标和数字,以便有一个类似的文件格式

先谢谢你

“真实”文件中的一部分:

新例子 预期产出:

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
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
输出如下

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


第二种解决方案:考虑到您需要对eg进行索引-->
chr13363456573659
10执行以下操作

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
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
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.
awk-F“[>:|]”##为输入文件的所有行将字段分隔符设置为>或:或。
NF>1&/^>/{##检查条件如果NF>1且行从>开始,则执行以下操作。
对于(i=3;iEDIT2:,因为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
输出如下

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


第二种解决方案:考虑到您需要对eg进行索引-->
chr13363456573659
10执行以下操作

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
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
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.
awk-F“[>:|]”##为输入文件的所有行将字段分隔符设置为>或:或。
NF>1&/^>/{##检查条件如果NF>1且行从>开始,则执行以下操作。
对于(i=3;i
返回:

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
返回:

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


您的示例输入\ u文件和预期输出不匹配,请检查一次,如果没有问题,请更正,否则请告诉我们获取该文件背后的逻辑。您的输出与接受的答案输出不同,哪一个是预期的?@KGeles,我的答案在您的问题编辑后更新,希望是giv现在输入相同的输出,请确认一次。@KGeles我编辑了我的答案以符合您的新规格您的示例输入文件和预期输出不匹配,请检查一次是否正确,如果不正确,请更正它,否则请让我们知道获取它的逻辑。您的输出与接受的答案输出不同,是哪一个是预期的吗?@KGeles,我的答案在您的问题编辑后会更新,我希望它现在给出相同的输出,请确认一次。@KGeles我编辑了我的答案以适应您的新规范。请让我不同意,我认为将命令分为两个定义的步骤是合适的。@KGeles再次编辑,如果我们不使用
排序
,它是j这是一个保护你的思想memory@KGeles无聊、固执和愿意改进的微妙组合让我花时间回答(我从RavinderSingh13的回答和EdMorton的评论中学到了新东西).Credit不能帮助我取得进步,但你的建议很好。@KGeles,我对要求很困惑,将尝试完成它。但我总是选择正确答案,总是选择OP,干杯。@RavinderSingh13只有当重复项出现在同一行时,你才需要删除它们。我删除重复项的关键是:第n行编号、名称(
Chr13
例如)和值(
923456-923659
例如)。括号中的内容(
(3C->A)
)不要数数。我不认为以前有过一个关键的元素。让我不同意,我认为在两个定义的步骤中拆分命令是合适的。@ KGeles再次编辑,如果我们不使用<代码>排序< /代码>,这只是一个想法来保护你的。memory@KGeles无聊、固执和愿意改进的微妙组合使me花时间回答(我从RavinderSingh13的回答和EdMorton的评论中学到了新东西).Credit不能帮助我取得进步,但你的建议很好。@KGeles,我对要求很困惑,将尝试完成它。但我总是选择正确答案,总是选择OP,干杯。@RavinderSingh13只有当重复项出现在同一行时,你才需要删除它们。我删除重复项的关键是:第n行名称(<代码> CHR13< /代码>)和值(例如代码> 923、45、923、6965、<或代码>)。括号内的内容(<代码>(3C--A) >不计数。我不考虑以前有过键的元素。@ RavundReNSIH13。我同意OP不清楚,但是您的输出文件不同。您需要使用CHR和(->)。删除副本的信息例如,您应该打印
Chr14 149656 149690 893
,因为
Chr14(4T->A)
已在第
行Chr14 463456 463669 12321中使用
@KGeles当然两个脚本返回不同的输出。在您的示例中,“我的解决方案”返回预期的输出,此脚本不返回not@KGeles,请尝试我的编辑解决方案,然后让我知道?@KGeles,我无法从office访问该文件,我将回家试用,什么不是实际工作?@RavinderSingh13我同意OP不清楚,但您的输出文件不同。您需要使用Chr和(->)信息删除副本。例如,您应该打印
CHR149656 149690 893