1. 程式人生 > 其它 >shell指令碼之sed使用----替換、變數、轉義字元

shell指令碼之sed使用----替換、變數、轉義字元

sed替換的基本語法為:
----s後面跟的是分隔符,原字串可使用.*這種正則表示式進行整行替換

sed 's/原字串/替換字串/'

單引號裡面,s表示替換,三根斜線中間是替換的樣式,特殊字元需要使用反斜線”\”進行轉義,但是單引號”‘”是沒有辦法用反斜線”\”轉義的,這時候只要把命令中的單引號改為雙引號就行了,例如:

sed "s/原字串包含'/替換字串包含'/" //要處理的字元包含單引號


命令中的三根斜線分隔符可以換成別的符號,這在要替換的內容有較多斜線是較為方便,只需要緊跟s定義即可,例如換成問號”?”:

sed 's?原字串?替換字串?' //自定義分隔符為問號


可以在末尾加g替換每一個匹配的關鍵字,否則只替換每行的第一個,例如:

sed 's/原字串/替換字串/' //替換所有匹配關鍵字


上箭頭”^”表示行首,美元”$”符號如果在引號中表示行尾,但是在引號外卻表示末行(最後一行),這裡犯二了,搜了半天哪個符號表示首行,半天才想起來,首行就是數字”1″啊.那麼在行首和行尾新增字串就是把行尾和行首替換,例如:

sed 's/^/新增的頭部&/g' //在所有行首新增
sed 's/$/&新增的尾部/g' //在所有行末新增
sed '2s/原字串/替換字串/g' //替換第2行
sed '$s/原字串/替換字串/g' //替換最後一行
sed '2,5s/原字串/替換字串/g' //替換2到5行
sed '2,$s/原字串/替換字串/g' //替換2到最後一行


替換樣式可以多個在同一條命令中執行,用分號”;”分隔,例如:

sed 's/^/新增的頭部&/g;s/$/&新增的尾部/g' //同時執行兩個替換規則

sed處理過的輸出是直接輸出到螢幕上的,要儲存可以將輸出重定向,或者使用引數”i”直接在檔案中替換:

sed -i 's/原字串/替換字串/g' filename //替換檔案中的所有匹配項

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

首先是Sed裡使用變數的問題

網上有人總結了四種方案:

1.       eval sed 's/$a/$b/' filename

2.       sed "s/$a/$b/" filename

3.       .sed 's/'$a'/'$b'/' filename

4.       .sed s/$a/$b/ filename

我比較喜歡第二種,也就是:Sed後面的表示式一般用單引號引起來('),當需要使用變數時就換用雙引號(")。

關於單雙引號的區別:

單引號:shell處理命令時,對其中的內容不做任何處理。即此時是引號內的內容是sed命令所定義的格式。

雙引號:shell處理命令時,要對其中的內容進行算術擴充套件。如果想讓shell擴充套件後得到sed命令所要的格式,使用命令:

sed -n "/\\\\$/p"

haha,擴充套件後得到的結果即\\$.

因此對於語句類似:

 $Comfilename="/home/evan/sandbox/Main/"

1. echo $Comfilename | sed 's#\/#\\\/#g'

2. echo $Comfilename | sed "s#\/#\\\/#g"

第一個的結果是:\/home\/evan\/sandbox\/Main\/

而第二個還是:/home/evan/sandbox/Main/因為雙引號會將“\/“解釋為”/“,所以sed "s#\/#\\\/#g"被Shell解釋成了sed s#/#\/#g到sed裡執行時又把”\/“轉義為”/“了,這樣相當於進行了了兩次解釋,就得不到想要的結果了。

這個例子告訴我當沒必要用雙引號的的時候就不要用,要不然說不定什麼時候你就會很鬱悶。當然單引號效率要比雙引號高也是不要濫用雙引號的原因之一。

言歸正傳,如何在sed的變數裡使用那些特殊的需要轉義的字元呢?

網上提出的一種方法是將sed裡表示替換用的s後面的表示分隔用的字元換成別的變數裡沒有的字元這樣就相當於變數裡沒有要轉義的字元了。

如:

sed –i "s# $Comfilename#/Root/#" filename.list

這是一個好辦法。但很不幸我需要的是刪除“d”不是替換“s“。當我把同樣的方法用於刪除時似乎沒有起到作用:

sed –i "# $Comfilename#d" filename.list

於是只能自己手工先改寫變數

 $Comfilename="/home/evan/sandbox/Main/"

Tempname=` echo $Comfilename | sed 's#\/#\\\/#g'`  (這裡把反單引號執行的結果給臨時變數,同樣的方法可以改寫其他需要轉義的符號。)

sed –i "# $ Tempname #d" filename.list
宣告 歡迎轉載,但請保留文章原始出處:) 部落格園:https://www.cnblogs.com/chenxiaomeng/ 如出現轉載未宣告 將追究法律責任~謝謝合作