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
):
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. )