本文首發於我的Github博客
本文記錄了作者在使用sed
命令進行文本替換時,對於使用到的替換模式進行轉義處理使用到的sed
命令,簡單來說:
- 使用
sed -e 's/[]\/$*.^[]/\\&/g'
即可對輸入字符串進行轉義
場景
sed
命令常常被用來對文本做處理,其中一個最經常用到的處理就是替換,替換的語法如下:
echo $STRING | sed -e 's/<match_pattern>/<replace_pattern>/g'
當然也可以有其他的變化,不過這是作者使用的最多的方式。
在使用這些的時候,我們可能會在match_pattern
和replace_pattern
中引用變量,已達到分別管理和增強可讀性的目的,比如
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="ff"
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")
但是,如果上面引用的REPLACE
裏面有特殊字符,我們就會遇到問題,比如
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="/a"
# 有問題
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")
我們的本意是將a
替換爲/a
,但是,使用這幾條命令,會得到
sed: 1: "s/a//a/g
": bad flag in substitute command: 'a'
這裏的原因就是/a
中的/
是一個特殊字符,如果希望得到我們上述的效果,應該這麼操作
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="\/a"
# 成功
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")
我們通過\/
進行轉義,取得了成功,但是這種方式使得我們編寫replace_pattern
變得麻煩,而且很不直觀,我們希望有一個函數來達到如下效果
# dummy text
TEXT="affaflns,fakfnakn"
REPLACE="/a"
REPLACE=$(func $REPLACE)
REPLACED_TEXT=$(echo $TEXT | sed -e "s/a/$REPLACE/g")
也就是說,編寫replace_pattern
時,可以直接編寫,而後使用一個函數或者命令自動轉義再使用
解決方案
使用sed -e 's/[]\/$*.^[]/\\&/g'
即可
方案解析
我們這次的方案就是對原生的replace_pattern
做一次替換:
match_pattern
爲[]\/$*.^[]
- 這個正則表達式的結構很具有迷惑性,其實它是一個大的bracket group
- 也就是說,實際上是
[
]\/$*.^[
]
的結構 - 意味着匹配
]\/$*.^[
中的任一字符
replace_pattern
爲\\&
- 這個
replace_pattern
用到了一個轉義字符和一個特殊字符 - 轉義字符
\\
表示的就是\
- 特殊字符
&
表示的是match_pattern
匹配到的內容
- 這個
綜合起來,這個替換語句就是把]\/$*.^[
前面全部加上一個斜槓,進行轉義