Grep e ordenar várias coisas não ordenadas em várias linhas (em um documento)

1

Eu tenho um arquivo com várias coisas não ordenadas em uma linha que quero colocar em um novo arquivo Este é um exemplo de parte do arquivo que tenho:

X1314448: SaMi|SM_g2554.t1 SaMi|SM_g5072.t1 Des|Des_g3808.t1 Dul|Dul_comp50786_c0_seq1-1 Nig|Nig_comp88811_c0_seq2-1 AB|AB0003DMP400018076_AB0003DMT400026495 Phy|Phy_comp35647_c0_seq1-1 SWtf|SW_g27807.t1 Tom|Solyc02g077050.2.1
X1314810: Des|Des_g33587.t1 Nig|Nig_comp84357_c0_seq1-1 AB|AB0003DMP400020961_AB0003DMT400030857 Phy|Phy_comp33112_c0_seq1-1 SaMi|SM_g27352.t1 SWtf|SW_g21774.t1 TAIR|AT4G14930.1 Tom|Solyc06g054250.2.1 Dul|Dul_comp63657_c0_seq2-1
X1327159: AB|AB0003DMP400016823_AB0003DMT400024599 AB|AB0003DMP400017933_AB0003DMT400026257 Dul|Dul_comp58749_c0_seq2-1

X1330513: Des|Des_g36886.t1 AB|AB0003DMP400049952_AB0003DMT400073802 SWtf|SW_g16502.t1

X132738: Des|Des_g491.t1 Des|Des_g6171.t1 Dul|Dul_comp57659_c0_seq2-1 Dul|Dul_comp57659_c0_seq3-1 Dul|Dul_comp57659_c0_seq4-1 Ni                                                                       g|Nig_comp93106_c3_seq1-1 Nig|Nig_comp93106_c3_seq2-1 AB|AB0003DMP400005485_AB0003DMT400007895 AB|AB0003DMP400021388_PGS                                                                       C0003DMT400031553 Phy|Phy_comp61931_c0_seq1-1 Phy|Phy_comp61931_c0_seq2-1 Phy|Phy_comp61931_c0_seq3-1 Phy|Phy_comp61931_c0_seq4-1                                                                        RICE|LOC_Os08g43334.1 RICE|LOC_Os08g43334.2 RICE|LOC_Os09g35790.1 RICE|LOC_Os09g35790.2 SaMi|SM_g30888.t1 SaMi|SM_g5888.t1 SWtf|SW                                                                       _g17547.t1 SWtf|SW_g33717.t1 Des|Des_g47565.t1 SaMi|SM_g6027.t1 SWtf|SW_g42019.t1 TAIR|AT5G62020.1 Tom|Solyc03g026020.2.1 TAIR|AT4                                                                       G11660.1

O que eu quero é ter a primeira parte, "X1314448:" seguido de "Des | Des_g3808.t1". E se houver outro "Des_xxx" (em alguns casos, há mais de um, como no segundo para a última linha), eu quero que isso seja incluído também, seguido pelo “AB | AB00…” no arquivo de saída, mas como é uma lista não classificada, não tenho certeza sobre como separar as três partes diferentes que eu quero mantê-los na mesma linha (mantendo-os ligados uns aos outros) .Eu também não sei como obter vários jogos em uma linha como esta.

Portanto, para a primeira linha, a saída deve ser:

X1314448: Des|Des_g3808.t1 AB|AB0003DMP400018076_AB0003DMT400026495 

Do segundo ao último último:

X1330513: Des|Des_g36886.t1 AB|AB0003DMP400049952_AB0003DMT400073802

para o último:

X132738: Des|Des_g491.t1 Des|Des_g6171.t1 Des|Des_g47565.t1 AB|AB0003DMP400005485_AB0003DMT400007895 AB|AB0003DMP400021388_PGSC0003DMT400031553

Eu acho que o principal problema é a última linha. Eu também quero poder modificar o arquivo para tenha o "Dul | ..." incluído também.

Solução:

Depois de trabalhar um pouco, acabei com: 1 - Salve este script como FastaToTbl e torne-o executável ( chmod 744 FastaToTbl ):

if (substr($1,1,1)==">")
       if (NR>1)
             printf "\n%s\t", substr($0,2,length($0)-1)
      else
         printf "%s\t", substr($0,2,length($0)-1)
       else
          printf "%s", $0
}END{printf "\n"}'  "$@"

2 - make e um segundo arquivo contendo este script: Use FastaToTbl combinado com este script para extrair os IDs de file1 e as sequências de file2 :

 ./mktbl file1[contains FASTA sequences] |
  perl -ne 'chomp;@a=split(/\t/); $k{$a[0]}=$a[1]; ## Collect the sequences
                                               ## $k{ID}=SEQUENCE
      END{open(A,"File02[contains my data that is missing FASTA sequences (ID file)]");   ## Open ID file
         while(<A>){         ## and process it line by line
           @a=split(/\s+/);  ## Gather the IDs in array @a
           print shift(@a);  ## Print the first element (Jan123:)
           print "$_ $k{$_}\n" for @a; ## Print each ID and its seq
 }}'
    
por Stenemo 13.06.2013 / 12:45

2 respostas

1

awk '/^ *$/ {next;}; NR>1 {print bufline;};
  {bufline=$1 " ";
    for (i=2;i<=NF;i++)
      { if ($i ~ "^Des\|" || $i ~ "^AB\|") bufline=bufline sprintf("%s ",$i);
        if ($i ~ "^Dul\|") dul=$i;
      };
  };
  END {print bufline " " dul;}' inputfile
    
por 13.06.2013 / 14:12
-1

Isso não funcionaria para você:

sort -k 2

Basicamente, a classificação por padrão definirá as colunas por espaços em branco. Você pode alterar essa opção como -t . Neste caso, estou dizendo para classificar pelo segundo campo. E a partir de um primeiro olhar, consegue o que você quer.

Se você quiser fazer uma classificação consecutiva, ainda poderá usar a classificação, adicionando opções -k extras. Fromt the man page:

   -k, --key=KEYDEF
          sort via a key; KEYDEF gives location and type

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a field number and C a character position in the field; both are origin 1, and the stop position defaults to the line's end

X1327159: AB|AB0003DMP400016823_AB0003DMT400024599 AB|AB0003DMP400017933_AB0003DMT400026257 Dul|Dul_comp58749_c0_seq2-1
X1314810: Des|Des_g33587.t1 Nig|Nig_comp84357_c0_seq1-1 AB|AB0003DMP400020961_AB0003DMT400030857 Phy|Phy_comp33112_c0_seq1-1 SaMi|SM_g27352.t1 SWtf|SW_g21774.t1 TAIR|AT4G14930.1 Tom|Solyc06g054250.2.1 Dul|Dul_comp63657_c0_seq2-1
X1330513: Des|Des_g36886.t1 AB|AB0003DMP400049952_AB0003DMT400073802 SWtf|SW_g16502.t1
X132738: Des|Des_g491.t1 Des|Des_g6171.t1 Dul|Dul_comp57659_c0_seq2-1 Dul|Dul_comp57659_c0_seq3-1 Dul|Dul_comp57659_c0_seq4-1 Ni 
    
por 13.06.2013 / 14:03