Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote -1 down vote accepted

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
share|improve this answer
    
This is exactly what I needed. Thank You! –  Ben Aug 3 '11 at 20:29
1  
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!) –  Gilles Aug 3 '11 at 20:32

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")'"
share|improve this answer
    
+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? –  glenn jackman Aug 4 '11 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. –  Gilles Aug 4 '11 at 16:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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