Reputation:
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
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
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
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
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
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