Linux Shell Bash Sed
Sed是非交互式的行編輯器.它即可以從stdin中接收文本輸入,也可以從文件中接收文本輸入, 它對(duì)輸入中的指定行進(jìn)行特定的操作,一行操作一次, 然后將結(jié)果輸出到stdout, 或輸出到文件中.在shell腳本中使用的話(huà),sed通常都是作為管道工具鏈中的一個(gè)處理部分來(lái)使用.
Sed會(huì)決定它需要處理那些行, 因?yàn)閟ed的參數(shù)就包含有地址范圍.
[1]既可以通過(guò)行號(hào)來(lái)指定地址范圍, 也可以通過(guò)模式匹配來(lái)決定地址范圍.比如, 3d表示sed會(huì)刪除輸入的第3行,/windows/d表示sed會(huì)刪除掉所有匹配"windows"的輸入行.
對(duì)于sed工具包的所有操作來(lái)說(shuō), 我們最關(guān)心的其實(shí)就是3個(gè)最主要的操作.分別是printing(打印到stdout),deletion(刪除),和substitution(替換).
表格 C-1. 基本sed操作
操作符名字效果
[地址范圍]/p 打印 打印[指定的地址范圍]
[地址范圍]/d 刪除 刪除[指定的地址范圍]
s/pattern1/pattern2/ 替換 將指定行中, 將第一個(gè)匹配到的pattern1, 替換為pattern2.
[地址范圍]/s/pattern1/pattern2/ 替換 在地址范圍指定的每一行中, 將第一個(gè)匹配到的pattern1, 替換為pattern2.
[地址范圍]/y/pattern1/pattern2/ transform 在地址范圍指定的每一行中, 將pattern1中的每個(gè)匹配到pattern2的字符都使用pattern2的相應(yīng)字符作替換. (等價(jià)于tr命令)
g 全局 在每個(gè)匹配的輸入行中, 將每個(gè)模式匹配都作相應(yīng)的操作. (譯者注: 不只局限于第一個(gè)匹配)
除非在替換命令的后邊明確指定選項(xiàng)g(全局), 否則的話(huà), 替換操作只會(huì)替換掉每行上的第一個(gè)模式匹配實(shí)例.
如果在命令行或腳本中使用這個(gè)命令, sed操作可能還需要某些選項(xiàng)和引用.
1 sed -e '/^$/d' $filename
2 # -e選項(xiàng), 將會(huì)使得后邊的字符被看作為編輯指令.
3 # (如果只給"sed"傳遞了單個(gè)指令, 那么"-e"是可選的.)
4 # "強(qiáng)"引用('')將會(huì)保護(hù)指令中的RE(正則表達(dá)式)字符串,
5 #+ 也就是防止腳本將RE重新解釋為特殊字符.
6 # (這會(huì)為sed命令, 保存指令的RE表達(dá)式.)
7 #
8 # 將會(huì)對(duì)文件$filename中的文本進(jìn)行操作.
在某些特定的情況下,sed編輯命令將不會(huì)和單引號(hào)的強(qiáng)引用一起工作.
1 filename=file1.txt
2 pattern=BEGIN
3
4 sed "/^$pattern/d" "$filename" # 工作正常.
5 # sed '/^$pattern/d' "$filename" 就會(huì)出現(xiàn)異常的結(jié)果.
6 # 在這個(gè)實(shí)例中, 被強(qiáng)引用(' ... ')引起的
7 #+ "$pattern"就不會(huì)擴(kuò)展為"BEGIN".
Sed命令的-e選項(xiàng)表示后續(xù)的字符串是一個(gè)指令, 或指令集. 如果后續(xù)的字符串中只有一個(gè)指令, 那么-e選項(xiàng)可以被省略.
1 sed -n '/xzy/p' $filename
2 # -n選項(xiàng)會(huì)讓sed只打印那些匹配模式的行.
3 # 否則所有的輸入行都會(huì)被打印.
4 # 這里可以省略-e選項(xiàng), 因?yàn)檫@里只有一個(gè)編輯指令.
表格 C-2. sed操作符舉例
表示法效果
8d 刪除輸入的第8行.
/^$/d 刪除所有空行.
1,/^$/d 從輸入的開(kāi)頭一直刪除到第1個(gè)空行(第一個(gè)空行也刪除掉).
/Jones/p 只打印那些包含"Jones"的行(使用-n選項(xiàng)).
s/Windows/Linux/ 在每個(gè)輸入行中, 將第一個(gè)出現(xiàn)的"Windows"實(shí)例替換為"Linux".
s/BSOD/stability/g 在每個(gè)輸入行中, 將所有"BSOD"都替換為"stability".
s/ *$// 刪除掉每行結(jié)尾的所有空格.
s/00*/0/g 將所有連續(xù)出現(xiàn)的0都?jí)嚎s成單個(gè)的0.
/GUI/d 刪除掉所有包含"GUI"的行.
s/GUI//g 將所有"GUI"都刪除掉, 并保持剩余部分的完整性.
在輸入行中, 將一個(gè)字符串替換為空字符, 等價(jià)于刪除這個(gè)字符串.剩余部分會(huì)保持完整. 比如s/GUI//, 拿下邊這句為例:
The most important parts of any application are its GUI and sound effects
結(jié)果為: The most important parts of any application are its and sound effects
反斜線(xiàn)將會(huì)強(qiáng)制sed替換命令延續(xù)到下一行.類(lèi)似于, 在第一行的結(jié)尾使用換行作為替換字符串.
1 s/^ */\
2 /g
這將每行開(kāi)頭的空格用換行來(lái)替換.最后的結(jié)果就是將每段的縮進(jìn)替換為一個(gè)空行.
地址范圍后邊可以加上一系列操作,這些操作可能需要放到大括號(hào)對(duì)中, 并且需要重起一行.
1 /[0-9A-Za-z]/,/^$/{
2 /^$/d
3 }
這只會(huì)刪除連續(xù)空行中的第一行.對(duì)于單行間距的文本文件來(lái)說(shuō), 這很有用, 但是會(huì)保留段落間的空行.
將文本文件雙倍行距的快速方法是sed G filename.