4

Part of the Korn script I am writing requires that I replace all occurrences of the ' character with two occurrences (''). I am trying to log some SQL that I am generating in this script to a column in another table but single quotes need to be replaced with 2 instances of the single quote character. I know there must be examples of this functionality somewhere but I'm not finding a string replace example specific to variables anywhere.

2 Answers 2

7

In ksh93 and zsh, there's a string replacement construct ${VARIABLE//PATTERN/REPLACEMENT}, used twice in the following snippet: once to replace ' by '' and once to replace newlines by '+char(10)+'. If there are no newlines in the input string, you can omit the second assignment command.

quoted_string=\'${raw_string//\'/\'\'}\'
quoted_string=${quoted_string//$'\n'/"'+char(10)+'"}

This construct is also available in bash, but the quoting rules are different. The following snippet works in all of ksh93, bash and zsh.

quoted_string=\'${raw_string//$'\''/$'\'\''}\'
quoted_string=${quoted_string//$'\n'/$'\'+char(10)+\''}

In ksh88 and other shells, you need to write a relatively complex loop to replace the single quotes one at a time. The following snippet doubles single quotes, but leaves newlines unchanged).

q="$raw_string"; quoted_string=
while
    quoted_string="$quoted_string'${q%%\'*}'"
    case "$q" in *\'*) q="${q#*\'}";; *) false;; esac
do :; done

Alternatively, you can use sed. Be careful when feeding the data to sed, as echo doesn't always print its argument as-is.

quoted_string="'$(printf '%s\n' "$raw_string" |
                  sed -n -e "s/'/''/g" -e 'H' \
                      -e '$ g' -e 's/^\n//' -e "s/\\n/'+char(10)+'/g" -e '$ p')'"

If there are no newlines in the string, the following much simpler sed command suffices.

quoted_string="'$(printf '%s\n' "$raw_string" | sed -e "s/'/''/g")'"
2
  • +1. With the last example, I'm getting the warning "sed: Missing newline at end of file standard input." -- do you mean printf "%s\n" instead of %s? Commented Aug 4, 2011 at 15:09
  • @glenn Yes (I tested but with GNU sed which doesn't care about final newlines). Thanks for that; also your comment made me realize it would be a good idea to replace with newlines in the input string, even if this wasn't in Ben's question. Commented Aug 4, 2011 at 16:14
-1

Is there any particular reason you couldn't call sed from within your ksh script?

This simple script:

#!/bin/ksh

foo="left ' right"
echo $foo
foo=$(echo "$foo" | sed "s#\'#\'\'#g")
echo $foo

gives me this output:

left ' right
left '' right
1
  • 2
    Always double quote variable substitutions. As written, this mangles whitespace and shell wildcard characters; that leaves ample holes for an attacker. @Ben do not use this code, it's broken. (I usually fix rather than downvote in such cases, but this is a question about quoting!) Commented Aug 3, 2011 at 20:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .