substitua tudo e mova a palavra para a posição final

0

talvez minha pergunta seja respondida de duas maneiras, mas espero que isso possa ser feito em um "sed":

Eu tenho as seguintes linhas, com diferentes IDs:

ID1_TRINITY_DN120587_c0_g1::TRINITY_DN120587_c0_g1_i1::g.8298::m.8298

e gostaria de receber:

TRINITY_DN120587_c0_g1_i1[ID1]

Eu realmente gostaria da sua contribuição / ajuda

Obrigado!

    
por gusa10 05.07.2017 / 19:12

3 respostas

1

sed -e '
   s/::/\n/;s//\n/
   s/^\([^_]*\)_.*\n\(.*\)\n.*/[]/
   ;#  |--1---|      |-2-|
' ID.data

Coloque os marcadores ao redor da string de ID e pegue a parte antes da primeira _ e substitua a linha inteira por esses valores. Saída:

TRINITY_DN120587_c0_g1_i1[ID1]

Explicação

              ID1_TRINITY_DN120587_c0_g1::TRINITY_DN120587_c0_g1_i1::g.8298::m.8298
              |-|                         |-----------------------|

Você disse que queria que o ID extraído entre a primeira e a segunda ocorrências de:

Passo-1: Coloque um marcador (geralmente um \ n) em torno da região de interesse:

       s/::/\n/;s//\n/

   This is how the pattern space looks after the above tranformation

              ID1_TRINITY_DN120587_c0_g1\nTRINITY_DN120587_c0_g1_i1\ng.8298::m.8298

Passo-2: extrair o ID que é a coisa entre os dois \ ns, bem como a string para o         esquerda da primeira ocorrência de _

                    s/^\([^_]*\)_.*\n\(.*\)\n.*/[]/
                    ;#  |------|      |---|
                    ;#                

   [^_]       => matches any char but an underscore

   [^_]*      => matches 0 or more non underscore char(s)

   \([^_]*\)  => store what was matched into a memory, recallable as 

   ^\([^_]*\) => anchor your matching from the start of the string

   .*\n       => go upto to the rightmost \n you can see in the string

   \n\(.*\)\n => Ooops!! we see another \n, hence we need to backtrack to
                 the previous \n position and from there start moving right again
                 and stop at the rightmost \n. Whatever is between these positions
                 is the string ID and is recallable as . Since the \ns fall outside
                 the \(...\), hence they wouldn't be stored in .

   .*         => This is a catchall that we stroll to the end of the string after
                 starting from the rightmost \n position and do nothing with it.

 So our regex engine has matched against the input string it was given in
 the pattern space and was able to store in two memory locations the data
 it was able to gather, viz.:  => stores the string portion which is in
 between the beginning of the pattern space and the 1st occurrence of the
 underscore.

  => store the string portion which is in between the 1st and 2nd
       occurrences of :: in the pattern space.

                       = ID1
                       = TRINITY_DN120587_c0_g1_i1

 Now comes the replacement part. Remember that the regex engine was able to scan
 the whole of pattern space from beginning till end, hence the replacement
 will effect the whole of the pattern space.

 [] => We replace the matched portion of the pattern space (in our case it
           happens to be the entire string) with what has been stored in
           the memory  literal [ memory  literal ]
           leading to what we see below:

                  TRINITY_DN120587_c0_g1_i1[ID1]

In other words, you have just managed to turn the pattern space from:

              ID1_TRINITY_DN120587_c0_g1::TRINITY_DN120587_c0_g1_i1::g.8298::m.8298

into the following:

                  TRINITY_DN120587_c0_g1_i1[ID1]
    
por 05.07.2017 / 19:24
0
Solução

awk :

awk -F'::' '{ print $2"[" substr($1,1,index($1,"_")-1) "]"}' file

A saída:

TRINITY_DN120587_c0_g1_i1[ID1]
  • -F'::' - separador de campos

  • substr($1,1,index($1,"_")-1) - extrair substring do primeiro campo a partir da primeira posição até a primeira ocorrência de _ (ou seja, ID1 )

por 05.07.2017 / 19:43
0

Estou assumindo aqui que seu padrão permanecerá o mesmo, esta única solução sed deve funcionar.

sed -n "s/^\([^_]*\)_[^:]*::\([^:]*\)::.*/\[\]/p" filename

Saída por exemplo de entrada:

TRINITY_DN120587_c0_g1_i1[ID1]

Explicação: Comece do início da linha, combine o conteúdo até o primeiro sublinhado [^_]* e armazene-o no primeiro grupo, depois combine o segundo grupo entre o primeiro e o segundo cólon duplo [^:]* . Substitua esta linha e combine com o formato de saída desejado, p imprime a linha modificada.

    
por 06.07.2017 / 09:23