lth
lth

Reputation:

Escape a string

I'm writing a shell script and I want to escape a string. Is there any way to convert this:

I'm happy.
You're sad.

to

I\'m happy.\nYou\'re sad.

I'm pretty sure there's some combination of sed/awk that does this....

Thanks

Upvotes: 5

Views: 2356

Answers (5)

Dmitri Sologoubenko
Dmitri Sologoubenko

Reputation: 2909

You can use plain Bash for that (see http://tldp.org/LDP/abs/html/string-manipulation.html).

Something like:

#!/bin/bash
X="I'm happy.
You're sad."
echo "========== BEFORE =========="
echo "${X}"
echo "========== AFTER ==========="
X="${X//\'/\\\'}"
X="${X//$'\n'/\\n}"
echo "${X}"
echo "============================"

Will produce output:

========== BEFORE ==========
I'm happy. You're sad.
========== AFTER ===========
I\'m happy.\nYou\'re sad.
============================

Upvotes: 1

mschilli
mschilli

Reputation: 1894

Here is my solution using awk:

$ awk '{$1=$1}1' FS=\' OFS="\\\'" ORS='\\n' <<< "I'm happy.
You're sad."

This results in the output

I\'m happy.\nYou\'re sad.\n

Explanation:

I set the Field Separator (FS) to ' (escaping it for the shell as \') and the Output Field Separator (OFS) to \' (wrapped in"..." to escape the ' for the shell and escaping the \ twice, once for the shell and a second time for awk, as "\\\'"). Without further options, the Record Separator (RS) is the newline character, but I set the Output Record Separator (ORS) to \n (again escaping the \ for awk as \\n).

Now the only thing left to tell awk to do is to re-calculate each record (by setting $1 to $1, nothing changes, but awk thinks the record changed, effectively substituting FS by OFS und thus every ' by \') and print each record (this is what the 1 pattern does: 1 is true for all records and since no action was given, the standard action {print $0} is performed), effectively substituting RS by ORS and thus every newline by \n.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753515

I think this does what you're after. The sequencing of the operations in the sed command is quite critical. Note that this also deals with backslashes (as well as single quotes) in the string (my PS1 prompt is Osiris JL:):

Osiris JL: cat zzz
xxx="I'm happy.
You're sad."
yyy=$(echo "$xxx" | sed 's/[\'\'']/\\&/g;s/$/\\n/;$s/\\n$//')
echo "$xxx"
echo $xxx
echo "$yyy"
echo $yyy
#eval echo $yyy
#eval echo "$yyy"
Osiris JL: sh zzz
I'm happy.
You're sad.
I'm happy. You're sad.
I\'m happy.\n
You\'re sad.
I\'m happy.\n You\'re sad.
Osiris JL: 

Upvotes: 0

Andy White
Andy White

Reputation: 88345

This works for replacing the ' with \'.

echo "I'm happy. You're sad" | sed "s/'/\\\'/g"

Are you sure you want to replace the space between "happy." and "You're" with a \n? \n is a newline, but your original line doesn't seem to have a new-line there.

Upvotes: 0

Chaitan
Chaitan

Reputation: 266

try

sed 's/\\ /\\n/g' | sed 's/\\'/\\\'/g'

I probably messed up a few \ here. Best way is to try it yourself.

Upvotes: 0

Related Questions