2011-12-09 71 views
4

我怎樣才能解決這個問題:使用逃生文件名SED替代

abc="a/b/c"; echo porc | sed -r "s/^/$abc/" 
sed: -e expression #1, char 7: unknown option to `s' 

變量$abc的替代做得正確,但問題是,$abc包含一個斜槓,這混淆sed。我能以某種方式逃避這些斜線嗎?

回答

6

GNU manual for sed指出「在任何給定的s命令中,/字符可以被任何其他單個字符統一替換。」

因此,只要使用其它字符代替/,例如:

abc="a/b/c"; echo porc | sed -r "s:^:$abc:" 
  1. 不要使用可以在輸入中找到一個字符。我們可以使用上面的:,因爲我們知道輸入(a/b/c/)不包含:

  2. 小心字符溢出。

    • 如果使用"",bash將專門解釋一些字符,例如`(用於內聯執行),!(用於accessing Bash history),$(用於訪問變量)。

    • 如果使用'',Bash會將所有字符按字面意思排列,即使$

    • 兩種方法可以結合起來,這取決於你是否需要逃逸與否,如:

      abc="a/b/c"; echo porc | sed 's!^!'"$abc"'!' 
      
+0

WOw,這是一個很好的解決方案。我不知道你可以使用不同於'/'的東西。即使現在我知道了,但我在手冊中找不到它。 謝謝大家! – haelix

+0

@haelix我現在已經添加了對手冊的引用,該手冊描述了這個「技巧」,等等。 –

1

反斜線:

abc='a\/b\/c' 

空間填充....

+1

將反斜槓放入該字符串往往很煩瑣,這不僅是因爲您必須弄清楚shell何時會解釋它們,以及何時「sed」將解釋它們。 –

7

注意sed(1)允許您使用不同的字符爲您s///分隔符:

$ abc="a/b/c" 
$ echo porc | sed -r "s|^|$abc|" 
a/b/cporc 
$ 

當然,如果你去這條路線,你需要確保你選擇的分隔符不會在你輸入的其他地方使用。

3

您不必使用/的模式和替換分離器,正如其他人已經告訴你的。我會用:,因爲它很少用於路徑(它是PATH環境變量中的分隔符)。堅持一個,並使用外殼內置的串替換功能,使其防彈,例如${abc//:/\\:}(這意味着在:是分隔符的情況下,用\:代替:的所有發生${abc})。

$ abc="a/b/c"; echo porc | sed -r "s:^:${abc//:/\\:}:" 
a/b/cporc 
+0

呃,實際上它並不是防彈的,因爲'\ n'這樣的'$ abc'仍然會被解釋,但它離我們更近了一步。 – przemoc

0

至於問題的轉義部分,我有同樣的問題,並解決了可以優化的雙sed。

escaped_abc=$(echo $abc | sed "s/\//\\\AAA\//g" | sed "s/AAA//g") 

三重一用,否則下面的轉義反斜線正斜槓永遠不會放在輸出,無論你把多少反斜槓在它的前面。