Использование awk для извлечения определенных «слов» с различными типами шаблонов (и возможных дублирующих записей) и создания нового файла с разделителями табуляции - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть много 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)

Проблемы:

  • В некоторых строках нет |и, вероятно, это вызывает первую проблему с выводом (не печатая 2-й столбец)
  • Как сохранить только одну запись в случае дубликатов / трехкратных повторов /...

ЧтоЯ ожидаю сделать это взять для каждого Chr * плюс координаты и число, чтобы иметь кровать -подобный формат файла

Заранее спасибо

Частьиз "реального" файла: 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 голосов
/ 20 ноября 2018
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
0 голосов
/ 20 ноября 2018

РЕДАКТИРОВАТЬ 2: Так как 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


1-е решение: Учитывая, что вам нужен индекс элементов, например -> 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


2-е решение: Учитывая, что вам нужно сделать индекс, например, -> 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.
...