2012-01-03 53 views
8

我想通過bash腳本中的sed腳本編輯文件。我希望以後很容易維護這個;易於理解和修改。替換字符串的樣子:如何在嵌入bash腳本的sed腳本中轉義反斜槓

PS1='\[\e[1;32m\][\[email protected]\h \W]\$\[\e[0m\]' 

在一個完美的世界,這將是這樣的:

sed -i "s/^PS1.*$/PS1='\[\e[1;32m\][\[email protected]\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\\\\][\\\\[email protected]\\\\h \\\\W]\\\\$\\\\[\\\\e[0m\\\\]'/g" /etc/skel/.bashrc 

我希望腳本爲可讀的,自包含的(不使用外部文件)。上述的任何替代方案?

+0

圍繞像regex這樣的任何東西使用單引號,除非你絕對需要一些插入到字符串中的變量。即使如此,在大多數正則表達式中使用單引號,只能在必須插入的部分周圍使用雙引號。使用一個組成的例子:'sed -e's /\.\*'"$ 1「'\ * \ ./ ab'」$ 2「'c'\''d /'$ 3'或者沿着這些線。序列'''''是您如何在命令行中嵌入單引號的方式;第一個單引號結束了當前的單引號部分;反斜槓引用將單個引號嵌入到字符串中;第三個單引號恢復單引號。 – 2012-01-04 14:16:35

回答

5

Bash的printf可以添加必要的轉義符,使字符串以可讀,可編輯的形式插入。

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

沒有試圖把它全部放在一條線上使整個事情更清晰。

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

使用帶有sed -f的sed腳本文件。這種方法也不是很漂亮,因爲它意味着有一個額外的文件躺在周圍,但至少避免了shell轉義。

+0

不想使用外部文件。 – hauptmech 2012-01-03 14:12:03

+0

您可以在這裏使用一些'sed'實現的文檔,即'sed -f - <<'EOF'' – tripleee 2012-01-03 16:49:37

4

這可能會爲你工作:

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

+1單引號是要走的路。 – tripleee 2012-01-03 16:50:40

+0

我發現單引號很難挑出,再加上替換字符串需要轉義,這使得它有點難以閱讀。 – hauptmech 2012-01-04 17:42:24

1

如何:

sed -i 's/^PS1.*$/PS1=SINGLEQUOTESLASH[SLASHe[1;32mSLASH][[email protected] 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 

分兩次做效率較低,但多幾個微秒是察覺到最多的人。

+0

我喜歡這裏正在發生的事情,但是sed需要\逃脫......所以它不會產生所需的輸出。 – hauptmech 2012-01-04 17:25:54

+0

@hauptmech我已經編輯它使用SLASH而不是'\'。現在看起來不太清晰。使用python或perl可能會更好 – 2012-01-04 19:02:46