Sed 命令詳解
一、簡介
sed是非交互式的流編輯器。它不會修改文件,除非使用shell重定向來保存結果。默認情況下,所有的輸出行都被打印到屏幕上。
sed編輯器逐行處理文件(或輸入),并將結果發(fā)送到屏幕。具體過程如下:首先sed把當前正在處理的行保存在一個臨時緩存區(qū)中(也稱為模式空間),然后處理臨時緩沖區(qū)中的行,完成后把該行發(fā)送到屏幕上。sed每處理完一行就將其從臨時緩沖區(qū)刪除,然后將下一行讀入,進行處理和顯示。處理完輸入文件的最后一行后,sed便結束運行。sed把每一行都存在臨時緩沖區(qū)中,對這個副本進行編輯,所以不會修改原文件。
sed命令格式
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
sed命令選項
| 選項 | 功能 |
|---|---|
| -e | 直接在命令行模式上進行sed動作編輯,此為默認選項 |
| -f | 將sed的動作寫在一個文件內,用–f filename 執(zhí)行filename內的sed動作 |
| -i | 直接修改文件內容 |
| -n | 只打印模式匹配的行 |
| -r | 支持擴展正則表達式 |
| -h --help | 顯示幫助 |
| -v --version | 顯示版本信息 |
sed常用命令
| 命令 | 功能 |
|---|---|
| a\ | 在當前行下面插入文本 |
| i\ | 在當前行上面插入文本 |
| c\ | 把選定的行改為新的文本 |
| d | 刪除,刪除選擇的行 |
| D | 刪除模板塊的第一行 |
| s | 替換指定字符 |
| h | 拷貝模板塊的內容到內存中的緩沖區(qū) |
| H | 追加模板塊的內容到內存中的緩沖區(qū) |
| g | 獲得內存緩沖區(qū)的內容,并替代當前模板塊中的文本 |
| G | 獲得內存緩沖區(qū)的內容,并追加到當前模板塊文本的后面 |
| l | 列表不能打印字符的清單 |
| n | 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令 |
| N | 追加下一個輸入行到模板塊后面并在二者間嵌入一個新行,改變當前行號碼 |
| p | 打印模板塊的行 |
| P | 打印模板塊的第一行 |
| q | 退出Sed |
| b | lable 分支到腳本中帶有標記的地方,如果分支不存在則分支到腳本的末尾 |
| r | file 從file中讀行 |
| t | label if分支,從最后一行開始,條件一旦滿足或者T,t命令,將導致分支到帶有標號的命令處,或者到腳本的末尾 |
| T | label 錯誤分支,從最后一行開始,一旦發(fā)生錯誤或者T,t命令,將導致分支到帶有標號的命令處,或者到腳本的末尾 |
| w | file 寫并追加模板塊到file末尾 |
| W | file 寫并追加模板塊的第一行到file末尾 |
| ! | 表示后面的命令對所有沒有被選定的行發(fā)生作用 |
| = | 打印當前行號 |
| # | 把注釋擴展到下一個換行符以前 |
sed替換標記
| 標記 | 作用 |
|---|---|
| g | 行內全局替換 |
| p | 打印行 |
| w | 把行寫入一個文件 |
| x | 互換模板塊中的文本和緩沖區(qū)中的文本 |
| y | 把一個字符翻譯為另外的字符(但是不用于正則表達式) |
| \1 | 子串匹配標記 |
| & | 已匹配字符串標記 |
sed元字符集
與grep一樣,sed也支持特殊元字符,來進行模式查找、替換。不同的是,sed使用的正則表達式是括在斜杠線"/"之間的模式。
如果要把正則表達式分隔符"/"改為另一個字符,比如o,只要在這個字符前加一個反斜線,在字符后跟上正則表達式,再跟上這個字符即可。例如:
sed -n '\o^Myop' datafile
| 元字符 | 作用 | 示例 |
|---|---|---|
| ^ | 行首定位符 | /^my/ 匹配所有以my開頭的 |
| $ | 行尾定位符 | /my$/ 匹配所有以my結尾的行 |
| . | 匹配除換行符外的單個字符 | /m..y/ 匹配包含字母m,后跟兩個任意字符,再跟字母y的行 |
| * | 匹配零個或多個前導字符 | /my*/ 匹配包含字母m,后跟零個或多個y字母的行 |
| [] | 匹配指定字符組內的任一字符 | /[Mm]y/ 匹配包含My或my的行 |
| [^] | 匹配不在指定字符組內的任一字符 | /[^A-RT-Z]ed/ 匹配非A-R和T-Z開頭,緊跟ed的行 |
| \(..\) | 保存已匹配的字符 | s/I\(love\)\(you\)/\2\1me Iloveyou -> youloveme |
| & | 保存查找串以便在替換串中引用 | s/love/**&**/,love -> **love** |
| \< | 詞首定位符 | /\<my/ 匹配包含以my開頭的單詞的行 |
| \> | 詞尾定位符 | /my\>/ 匹配包含以my結尾的單詞的行 |
| x\{m\} | 重復字符x,m次 | /0\{5\}/匹配包含5個0的行 |
| x\{m,\} | 重復字符x,至少m次 | /0\{5,\}/匹配至少有5個0的行 |
| x\{m,n\} | 重復字符x,至少m次,不多于n次 | /0\{5,10\}/匹配5~10個0的行 |
二、sed 定址
定址用于決定對哪些行進行處理。地址的形式可以是數(shù)字、正則表達式、或二者的結合。如果沒有指定地址,sed將處理輸入文件的所有行。
地址如果是一個數(shù)字,則表示某一行號;“$"符號表示最后一行。
地址如果由逗號分隔,則表示處理兩行之間的范圍(包括這兩行在內)。
# 只打印第三行
sed -n '3p' datafile
# 刪除第二至第五行
sed -i '2,5d' datafile
# 刪除包含'My'的行到包含'You'的行之間的行
sed -i '/My/,/You/d' datafile
# 刪除包含'My'的行道第十行之間的行
sed -i '/My/,10d' datafile
三、sed命令詳解
3.1 p 命令
命令p用于顯示模式空間的內容。默認情況下,sed把輸入行打印在屏幕上,選項-n用于取消默認的打印操作。當選項-n和命令p同時出現(xiàn)時,sed可打印選定的內容。
# 選項-n取消sed默認的打印,p命令把匹配模式my的行打印一遍
sed -n '/my/p' datafile
3.2 d 命令
命令d用于刪除輸入行。sed先將輸入行從文件復制到模式空間里,然后對該行執(zhí)行sed命令,最后將模式空間里的內容顯示在屏幕上。如果發(fā)出的是命令d,當前模式空間里的輸入行會被刪除,不被顯示。
#刪除包含my的行,其余的都被顯示
sed '/my/d' datafile
3.3 s 命令
命令s用于替換文本中的字符串,使用后綴 /g標記會替換每一行中的所有匹配
# 取消默認輸出,處理1到20行中匹配以My結尾的行,把行內所有的My替換為You,并打印到屏幕上
sed -n '1,20s/My$/You/gp' datafile
緊跟在s命令后的字符就是查找串和替換串之間的分隔符。分隔符默認為正斜杠,但可以改變。無論什么字符(換行符、反斜線除外),只要緊跟s命令,就成了新的串分隔符。
sed 's#My#Your#g' datafile
3.4 e 選項
-e是編輯命令,用于sed執(zhí)行多個編輯任務的情況。在下一行開始編輯前,所有的編輯動作將應用到模式緩沖區(qū)中的行上。
sed -e '1,3d' -e 's/My/Your/g' datafile
選項-e用于進行多重編輯。第一重編輯刪除第1-3行。第二重編輯將出現(xiàn)的所有My替換為Your。因為是逐行進行這兩項編輯(即這兩個命令都在模式空間的當前行上執(zhí)行),所以編輯命令的順序會影響結果。
3.5 r 命令
r命令是讀命令。sed使用該命令將一個文本文件中的內容加到當前文件的特定位置上。
#如果在文件datafile的某一行匹配到模式My,就在該行后讀入文件introduce.txt的內容。如果出現(xiàn)My的行不止一行,則在出現(xiàn)My的各行后都讀入introduce.txt文件的內容。
sed '/My/r introduce.txt' datafile
3.6 w 命令
# 在example中所有包含test的行都被寫入file里
sed -n '/test/w file' example
3.7 a\ 命令
a\命令是追加(行下)命令,追加將添加新文本到文件中當前行(即讀入模式緩沖區(qū)中的行)的后面。所追加的文本行位于sed命令的下方另起一行。如果要追加的內容超過一行,則每一行都必須以反斜線結束,最后一行除外。最后一行將以引號和文件名結束。
# 將 this is a test line 追加到 以test 開頭的行后面
sed '/^test/a\this is a test line' file
3.8 i\ 命令
i\ 命令是插入(行上)命令,在當前行的前面插入新的文本。
# 將 this is a test line 追加到以test開頭的行前面
sed '/^test/i\this is a test line' file
3.9 c\ 命令
sed使用該命令將已有文本修改成新的文本。
3.10 n命令
sed使用該命令獲取輸入文件的下一行,并將其讀入到模式緩沖區(qū)中,任何sed命令都將應用到匹配行緊接著的下一行上。
# 如果匹配到test,則移動至下一行,將此行中的My替換為Your,然后繼續(xù)
sed '/test/{n;s/My/Your/;}' datafile
如果需要使用多條命令,或者需要在某個地址范圍內嵌套地址,就必須用花括號將命令括起來,每行只寫一條命令,或者用分號分割同一行中的多條命令。
3.11 y命令
該命令與UNIX/Linux中的tr命令類似,字符按照一對一的方式從左到右進行轉換。例如,y/abc/ABC/將把所有小寫的a轉換成A,小寫的b轉換成B,小寫的c轉換成C。
# 把1~10行內所有abcde轉變?yōu)榇髮?sed '1,10y/abcde/ABCDE/' file
# y命令對正則表達式元字符不起作用
# 與s命令的分隔符一樣,斜線可以被替換成其它的字符
3.12 q命令
q命令將導致sed程序退出,不再進行其它的處理。
sed '/abcd/{s/abcd/ABCD/;q;}' datafile
3.13 h命令和g命令
在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩沖區(qū)中,除非行被刪除或者輸出被取消,否則所有被處理的行都將打印在屏幕上。接著模式空間被清空,并存入新的一行等待處理。
ed -e '/test/h' -e '$G' file
在這個例子里,匹配test的行被找到后,將存入模式空間,h命令將其復制并存入一個稱為保持緩存區(qū)的特殊緩沖區(qū)內。第二條語句的意思是,當?shù)竭_最后一行后,G命令取出保持緩沖區(qū)的行,然后把它放回模式空間中,且追加到現(xiàn)在已經存在于模式空間中的行的末尾。在這個例子中就是追加到最后一行。簡單來說,任何包含test的行都被復制并追加到該文件的末尾。
3.14 sed 腳本
sed腳本是一個sed的命令清單,啟動Sed時以-f選項引導腳本文件名。Sed對于腳本中輸入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多個命令,要用分號分隔。以#開頭的行為注釋行,且不能跨行。
四、sed 實例
4.1 sed 開關注釋行
# 注釋行
sed -i 's/^PasswordAuthentication/#&/' /etc/ssh/sshd_config
sed -i '/PasswordAuthentication/s/^/#/' /etc/ssh/sshd_config #這種方式不太推薦
# 取消注釋行
sed -i 's/^#\(PasswordAuthentication.*\)/\1/' /etc/ssh/sshd_config
sed -i '/PasswordAuthentication/s/#//' /etc/ssh/sshd_config #這種方式不太推薦