Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Currently I use:

sed -i -e "5a\\
${text}" $filename

to append something to a certain line, where the variable text contains a string such as "\epsilon".

When using

echo -E $text

the string is displayed just fine, but when I expand it in the string I pass to sed, all escape characters get expanded and the result is not what I would want.

How can I get sed to use the raw contents of that string without escaping anything?

share|improve this question
up vote 3 down vote accepted

The sed command a\ interprets escapes, so you need to duplicate backslashes in the string you are interpolating. Try this:

sed -e "5a\\
$(echo -E "$text" | sed -e 's/\\/\\\\/g')"
share|improve this answer
Thanks. I'll probably need to add escaping of $ as well. How many other special symbols that require escaping are possible for a bash string? – pmr Aug 10 '12 at 12:04
No, the shell doesn't do recursive interpolation. If you have a='AA' and b='this is $a', then echo $b will just print this is $a. Once you make echo output the correct string, you only need to worry about sed, and sed only interprets backslashes, which is taken care of with the inner sed. That's all. – angus Aug 10 '12 at 13:03

Quoting is tricky. I recommend using a tool that doesn't require you to add additional quotes, such as awk or perl. These two tools allow you to pass parameters on the command line or through the environment and use them in text manipulations. With Perl:

export text
perl -i -pe '$_ .= "$ENV{text}\n" if $. == 5' "$filename"

With awk, you need to do the file moving manually:

tmp=$(TMPDIR=$(dirname -- "$filename") mktemp)
awk -v text="$text" '{print} NR==5 {print text}' <"$filename" >"$tmp" &&
mv -- "$tmp" "$filename"
share|improve this answer

You can generally apply escaping with printf "%q", try this:

echo -e "$text"

with %q:

text=$(printf "%q" '\epsilon')
echo -e "$text"
share|improve this answer
Also a very nice solution although I went with the sed way. – pmr Aug 10 '12 at 13:22

As I am not a sed master, I find it easier to explain with echo.

Use single quotes instead of double quotes.


echo "one\\two"


echo 'one\two'

So, by using the example2 way, you don't have to escape anythin. The string inside the single quotes 's\t\r\i\n\g' is interpreted as it is. (The \ character does not work as an escape character)

source: one

share|improve this answer
That is useless. As you can see I need to expand a variable. That wouldn't happen if I were to use single quote escapes. – pmr Aug 10 '12 at 12:03

Your Answer


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.