sed
全稱:steam editor
單引號 & 雙引號 & 反引號
單引號
單引號內的字符都是普通字符,不會有任何特殊意義。包括轉義字符。所以會原樣輸出所有字符
雙引號
雙引號內的字符,$,\,` 這三種字符是有特殊意義的。其中$代表了引用變量的值,` 代表了引用的命令。反斜槓是用於轉義這兩個字符以及雙引號本身的。
如果想打印出這幾個特殊字符,就需要用轉議,否則會失敗
# 直接打印,會錯誤
[root@hadoop usr]# echo "`"
> ^C
#
反引號
反引號括起來的字符串會被識別為命令。其等價於$(),推薦使用後者,因為反引號容易和單引號混淆。
總結
- 當要匹配的字符串或用於替換的字符串中有單引號時,只能使用雙引號包圍。
- 當要匹配的或用於替換的含雙引號的時候,可以用單引號包圍,或用雙引號進行包圍並使用‘’進行轉義
- 在sed 命令中,引號的解析是shell進行的,sed命令只是獲取shell解析後的結果。而不同的shell解析的方式也可能不同。所以最安全的做法是寫在文件中,通過
sed -f執行,避免了引號的使用。
#錯誤用法--雙引號下會把 $s 解析成一個變量。所以會報錯。
sed "1,3s/my/your/g; 3,$s/This/That/g" my.txt
#正確用法--使用單引號,不會做任何解析
sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
#正確用法--轉義 $ 符號
sed "1,3s/my/your/g; 3,\$s/This/That/g" my.txt
匹配行
只替換每一行的第一個s:
$ sed 's/s/S/1' my.txt
只替換每一行的第二個s:
$ sed 's/s/S/2' my.txt
只替換第一行的第3個以後的s:
$ sed '1s/s/S/3g' my.txt
特殊符號和命令
1. &
&用於表示匹配到的結果。
2.圓括號
使用圓括號匹配的示例:(圓括號括起來的正則表達式所匹配的字符串會可以當成變量來使用,sed中使用的是1,2…)
$ sed 's/This is my \([^,&]*\),.*is \(.*\)/\1:\2/g' my.txt
3. BRE & ERE
基本正則表達式 和 擴展正則表達式
反斜槓用於對字符串中特殊字符的轉義。在使用圓括號時發現了一點疑問,網上給出的例子都需要對圓括號用\進行轉義,而這不就是匹配圓括號本身嗎?但是在實踐中發現,確實當不用轉義時會直接匹配字符,只有轉義後才會體現括號的作用。
如下面的例子:
#
$ echo "()" | sed 's/()/a/g'
a
#
$ echo "abc" | sed 's/\(b\)/\1\1/g'
abbc
而在之前學正則表達式的時候,是當需要匹配括號本身時才需要轉義的。而這就是 基本正則表達式 和 擴展正則表達式的區別了。
linux的文本處理命令中,grep和sed都只支持基本正則,而egrep和awk則支持擴展正則。但是grep和sed也可以分別通過-E 和-r參數來支持擴展正則
基本正則
基本正則的元字符有以下:
1. ^
2. $
3. .
4. *
5. []
6. \<
7. \>
8. \(\)
9. \?
10.\+
網上很多博客把?和+歸為擴展正則,但是注意在基本正則中,是有這兩個符號的,只是要通過轉義來使用
在linux中測試可以發現這兩個元字符都是可以正常使用的。
也有博客説|是擴展正則才有的
$ echo "ABC" | sed "s/A\+BC/DDD/"
DDD
$ echo "ABC" | sed "s/A\?BC/DDD/"
DDD
擴展正則
擴展正則只是把一些常用的元字符去掉了轉義,並且加了少量新的元字符。
1. +
2. ?
3. ()
所以就明白了為什麼在sed中的括號要進行轉義了。因為sed使用的是基本正則,所以要想不用反斜槓直接使用括號,那麼加上命令參數-r來讓sed支持擴展正則就可以啦。對於grep是一樣的道理,可以使用egrep或grep -E