Como faço para escrever um sed-one liner para adicionar um caractere após cada terceiro caractere?

10

Então, eu tenho uma string parecida com esta:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA

E eu quero dividir a string em trechos de 3 caracteres delimitados por um sinal "+".

AUG+GCC+AUG+GCG+CCC+AGA+ACU+GAG+AUC+AAU+AGU+ACC+CGU+AUU+AAC+GGG+UGA

E eu quero fazer isso com meu bom amigo sed .

Eu tentei

cat codons | sed -r 's/([A-Z]\{3\})/\+/g'

... sem sucesso.

Qual comando sed posso usar?

    
por ixtmixilix 21.12.2012 / 20:58

4 respostas

16

Como você não quer um + à direita, você pode fazer:

fold -w3 | paste -sd+ -

Isto é, fold as linhas no 3 caractere w idth, e cole aquelas 3 linhas de caracteres com eles s elfos com + como o elimitador d que, na verdade, é como alterar cada caractere de nova linha, mas o último em + . Se a entrada tiver mais de uma linha, você terminará com as linhas associadas a um + , que pode ou não ser o que você deseja.

Se você precisar que ele seja sed , você poderá remover o + final:

sed 's/.../&+/g;s/+$//'
    
por 21.12.2012 / 21:33
12
sed 's/.../&+/g'

para começar a trabalhar, você não precisa escapar de {} símbolos:

sed -r 's/([A-Z]{3})/+/g'
    
por 21.12.2012 / 21:03
2

Isso pode funcionar para você (GNU sed):

sed 's/...\B/&+/g' file
    
por 24.12.2012 / 10:11
0

Se sed não for necessário, o uso de Ruby pode ser uma alternativa. O interpretador Ruby, ruby , pode ser usado como sed e awk, executando-o com a opção -n , o que faz com que seja iterado sobre sua entrada. O intérprete pode então ser alimentado com um one-liner Ruby, adicionando-o como um argumento para a opção -e (que diz ao interpretador para interpretar o argumento de -e em vez de procurar um script em um arquivo). p>

Para este problema em particular, você pode usar o seguinte one-liner (adaptado do link ):

ruby -ne 'puts $_.scan(/.{3}|.+/).join("+")'

Em linguagem simples,

  • corresponde a 3 caracteres ou pelo menos um caractere, scan(/.{3}|.+/) , na string de entrada, $_ (neste caso, espera-se que a entrada venha da entrada padrão) e coloca cada correspondência em uma matriz,
  • une a matriz em uma string com um '+' conectando cada elemento, join("+") ,
  • e imprime terminado por uma nova linha puts .

Por exemplo

echo "AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUG" | ruby -ne 'puts $_.scan(/.{3}|.+/).join("+")'
AUG+GCC+AUG+GCG+CCC+AGA+ACU+GAG+AUC+AAU+AGU+ACC+CGU+AUU+AAC+GGG+UG

Observe que ele não adiciona nenhum '+' à direita.

    
por 21.12.2012 / 21:24