So, I have a string that looks like this:


And I want to split the string into 3-character chunks delimited by a '+' sign.


And I want to do that with my good friend sed.

I tried

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

...with no success.

What sed command can I use?

  • 1
    Aren't this somehow connected to Rosalind? Just curious. – m0nhawk Dec 21 '12 at 20:32

Since you don't want a trailing +, you could do:

fold -w3 | paste -sd+ -

That is, fold the lines on 3 character width, and paste those 3 character lines with themselves with + as the delimiter which in effect is like changing every newline character but the last one into a +. If the input had more than one line, you'll end up with those lines joined with a + which may or may not be what you want.

If you do need it to be sed, you can remove the trailing + after:

sed 's/.../&+/g;s/+$//'
  • Would you mind adding a short explanation of how that works? – N.N. Dec 21 '12 at 20:35
  • @N.N. It works because +$ matches a plus symbol immediately before the end of a line. – Chris Down Dec 21 '12 at 21:14
  • fold -w3 breaks the string into 3 character lines. paste -sd+ - turns the newlines into +. – bahamat Dec 22 '12 at 3:40
sed 's/.../&+/g'

to get your way working you don't need to escape {} symbols:

sed -r 's/([A-Z]{3})/\1+/g'
  • 1
    who knew! i was so close yet so far... thanks... – ixtmixilix Dec 21 '12 at 20:10
  • Both add a trailing '+'. Is this intended? – N.N. Dec 21 '12 at 20:25

This might work for you (GNU sed):

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

If sed is not a must using Ruby might be an alternative. The Ruby interpreter, ruby, can be used like sed and awk by running it with the -n option which makes it iterate over its input. The interpreter can then be feed with a Ruby one-liner by adding it as an argument to the -e option (which tells the interpreter to interpret the argument of -e rather than looking for a script in a file).

For this particular problem you can use the following one-liner (adapted from https://stackoverflow.com/a/3184271/789593):

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

In plain language it

  • matches any 3 characters or at least one character, scan(/.{3}|.+/), in the input string, $_ (in this case the input is expected to come from standard in) and puts each match in an array,
  • joins the array into a string with a '+' connecting each element, join("+"),
  • and prints it terminated by a newline puts.

For example

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

Note that it does not add any trailing '+'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.