如何在嵌入在bash脚本中的sed脚本中转义反斜杠

时间:2012-01-03 13:45:04

标签: bash sed escaping

我想通过bash脚本中的sed脚本编辑文件。我希望以后容易维护;易于理解和修改。替换字符串如下所示:

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

在一个完美的世界里,它会是这样的:

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

问题是bash和sed正在剥离\,在文件中给出以下结果:

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

显然不能使用单引号。一个强力解决方案是使用逃逸,但为了这个工作我得到一个非常难看的线:

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

我希望脚本可读且自包含(不使用外部文件)。上述任何替代方案?

4 个答案:

答案 0 :(得分:5)

Bash的printf可以添加必要的转义,让字符串以可读,可编辑的形式插入。

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

不试图将它全部放在一条线上会使整个事情变得更加清晰。

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

答案 1 :(得分:4)

这可能对您有用:

echo "PS1=abc" |
sed 's/^PS1.*$/PS1='\''\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\]'\''/'
PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\]'

答案 2 :(得分:1)

使用带有sed -f的sed脚本文件。这个替代方案也不是很漂亮,因为它意味着有一个额外的文件,但至少你可以避免shell转义。

答案 3 :(得分:1)

这个怎么样:

sed -i 's/^PS1.*$/PS1=SINGLEQUOTESLASH[SLASHe[1;32mSLASH][SLASHu@SLASHh SLASHW]SLASH$SLASH[SLASHe[0mSLASH]SINGLEQUOTE/g' /etc/skel/.bashrc
sed -i "s/SINGLEQUOTE/'/g" /etc/skel/.bashrc
sed -i "s/SLASH/\\/g" /etc/skel/.bashrc

在两次通过中执行它效率较低,但对于大多数人来说,几微秒是不明显的。