[bash] How to escape single quotes within single quoted strings

Here are my two cents -- in the case if one wants to be sh-portable, not just bash-specific ( the solution is not too efficient, though, as it starts an external program -- sed ):

  • put this in quote.sh ( or just quote ) somewhere on your PATH :
# this works with standard input (stdin)
quote() {
  echo -n "'" ;
  sed 's/\(['"'"']['"'"']*\)/'"'"'"\1"'"'"'/g' ;
  echo -n "'"
}

case "$1" in
 -) quote ;;
 *) echo "usage: cat ... | quote - # single-quotes input for Bourne shell" 2>&1 ;;
esac

An example:

$ echo -n "G'day, mate!" | ./quote.sh -
'G'"'"'day, mate!'

And, of course, that converts back:

$ echo 'G'"'"'day, mate!'
G'day, mate!

Explanation: basically we have to enclose the input with quotes ', and then also replace any single quote within with this micro-monster: '"'"' ( end the opening quote with a pairing ', escape the found single quote by wrapping it with double quotes -- "'", and then finally issue a new opening single quote ', or in pseudo-notation : ' + "'" + ' == '"'"' )

One standard way to do that would be to use sed with the following substitution command:

s/\(['][']*\)/'"\1"'/g 

One small problem, though, is that in order to use that in shell one needs to escape all these single quote characters in the sed expression itself -- what leads to something like

sed 's/\(['"'"']['"'"']*\)/'"'"'"\1"'"'"'/g' 

( and one good way to build this result is to feed the original expression s/\(['][']*\)/'"\1"'/g to Kyle Rose' or George V. Reilly's scripts ).

Finally, it kind of makes sense to expect the input to come from stdin -- since passing it through command-line arguments could be already too much trouble.

( Oh, and may be we want to add a small help message so that the script does not hang when someone just runs it as ./quote.sh --help wondering what it does. )