Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I escape backslashes in a sed script embedded in a bash script

Tags:

bash

escaping

sed

I want to edit a file via a sed script in a bash script. I want this to be easy to maintain later; easy to understand and modify. The replacement string looks like:

PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\]'

In a perfect world, it would like this:

sed -i "s/^PS1.*$/PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\]'/g" /etc/skel/.bashrc

The problem is that bash and sed are stripping out the \ giving the following result in the file:

PS1='[e[1;32m][@h W]$[e[0m]'

Obviously single quotes can't be used. A brute force solution is to use escapes, but for this to work I get a really ugly looking line:

sed -i "s/^PS1.*$/PS1='\\\\[\\\\e[1;32m\\\\][\\\\u@\\\\h \\\\W]\\\\$\\\\[\\\\e[0m\\\\]'/g" /etc/skel/.bashrc

I want the script to be readable and self contained (not using external files). Any alternatives to the above?

like image 516
hauptmech Avatar asked Jan 03 '12 13:01

hauptmech


People also ask

How do you escape special characters in sed?

Put a backslash before $. */[\]^ and only those characters (but not inside bracket expressions).

How do you escape a backslash in sed?

Use single quotes for sed and you can get away with two backslashes. echo "sample_input\whatever" | sed 's/\\/\//' Hopefully someone will come up with the correct explanation for this behavior.

How do you escape a backslash in Bash?

Escape characters are used to remove the special meaning from a single character. A non-quoted backslash, \, is used as an escape character in Bash.

How do you escape a forward slash in shell script?

You need to escape the / as \/ . The escape ( \ ) preceding a character tells the shell to interpret that character literally.


1 Answers

Bash's printf can add the necessary escapes, leaving the string to be inserted in an readable, editable form.

sed -i "s/^PS1.*$/$(printf "%q" "PS1='\[\e[1;32m\][\u@\h \W]$\[\e[0m\]'")/g" /etc/skel/.bashrc

Not trying to stick it all on one line makes the whole thing clearer.

REPL=$(printf "%q" "PS1='\[\e[1;32m\][\u@\h \W]$\[\e[0m\]'")
sed -i "s/^PS1.*$/$REPL/g" /etc/skel/.bashrc
like image 170
hauptmech Avatar answered Oct 06 '22 02:10

hauptmech