Comment puis-je écrire un one-liner sed pour append un caractère après chaque troisième caractère?

Donc, j'ai une string qui ressemble à ceci:

AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA 

Et je veux split la string en morceaux de 3 caractères délimités par un signe '+'.

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

Et je veux le faire avec mon bon ami sed .

j'ai essayé

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

… sans succès.

Quelle command sed puis-je utiliser?

Puisque vous ne voulez pas un + , vous pourriez faire:

 fold -w3 | paste -sd+ - 

C'est-à-dire, pliez les lignes sur 3 caractères et collez ces 3 lignes de caractères avec les elfes avec + comme elimiter, ce qui revient à changer chaque caractère de ligne, mais le dernier en a + . Si l'input a plus d'une ligne, vous vous refindez avec ces lignes jointes à un + qui peut ou ne peut pas être ce que vous voulez.

Si vous avez besoin d'être sed , vous pouvez supprimer le trailing + after:

 sed 's/.../&+/g;s/+$//' 
 sed 's/.../&+/g' 

pour vous frayer un path, vous n'avez pas besoin d'échapper aux symboles {} :

 sed -r 's/([AZ]{3})/\1+/g' 

Cela pourrait fonctionner pour vous (GNU sed):

 sed 's/...\B/&+/g' file 

Si sed n'est pas un must en utilisant Ruby pourrait être une alternative. L'interpréteur Ruby, ruby , peut être utilisé comme sed et awk en l'exécutant avec l'option -n qui le rend itéré sur son input. L'interpréteur peut alors être alimenté avec une ligne Ruby en l'ajoutant en argument à l'option -e (qui request à l'interpréteur d'interpréter l'argument de -e plutôt que de chercher un script dans un file).

Pour ce problème particulier, vous pouvez utiliser l'un-ligne suivante (adapté de https://stackoverflow.com/a/3184271/789593 ):

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

En clair, il

  • correspond à 3 caractères ou au less un caractère, scan(/.{3}|.+/) , dans la string d'input, $_ (dans ce cas, l'input devrait provenir de standard in) tableau,
  • joint le tableau dans une string avec un '+' connectant chaque élément, join("+") ,
  • et l'imprime terminé par une nouvelle ligne.

Par exemple

 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 

Notez qu'il n'ajoute aucun '+' de fin.