一、SED介紹
SED(Stream EDitor)是一個文本解析轉換工具。它遵循簡單的工作流:讀取、執行、顯示。
- 讀取:SED從輸入流(檔案,管道或者标準輸入)中讀取一行并且存儲到模式空間(pattern buffer)的内部緩沖區
- 執行:預設情況下,所有的SED指令都在模式空間中順序執行;而且SED指令将會在所有的行上依次執行,除非指定了行的位址
- 顯示:發送修改後的内容到輸出流。在發送資料之後,模式空間将會被清空
注意
- 模式空間是一塊緩沖區,在sed編輯器執行指令時會儲存待檢查的文本
- 預設情況下,所有的sed指令都是在模式空間中執行,是以輸入檔案并不會發生改變
- 還有另外一個緩沖區叫做保持空間(hold buffer),在處理模式空間中的某些行時,可以用保持空間來臨時儲存一些行。在每一個循環結束的時候,sed會移除模式空間中的内容,但是該緩沖區中的内容在所有的循環過程中是持久存儲的。
示例
首先檢視quote.txt檔案内容:

執行
sed '' quote.txt
結果如下:
處理流程:sed指令先将文本中的一行内容存儲到它的模式空間中,然後在緩沖區執行指令;此處沒有提供sed指令,是以對該緩沖區沒有要執行的操作;最後删除模式空間的内容,并列印該内容到标準輸出。最後流程總結如下:
一行内容->模式空間->執行指令->删除模式空間内容->列印
二、使用
2.1 基礎文法
sed -option 'command' file
2.1.1 指令說明
command | 說明 |
---|---|
d | 删除 (delete) |
s | 單個字元替換 (substitute) |
p | 列印 (print) |
w | 寫入 (write)指令 |
a | 追加 (append) |
c | 行替換 (change) |
i | 插入 (insert) |
l | 顯示隐藏字元 |
q | 退出指令 (quit) |
r | 檔案讀取 (read) |
e | 執行外部指令 |
! | 排除指令 |
-
d
books.txt内容如下:
執行shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
指令,删除第二行内容:sed '2d' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
s
執行
指令,給books.txt檔案每一行結尾加上感歎号:sed 's/$/!/'
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
p
首先看
指令執行結果:sed 'p' quote.txt
同shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
指令相比,每一行列印了兩次,這是因為在内容讀取進模式空間進行處理的時候,執行的指令是sed '' quote.txt
,列印内容(第一次),在處理完畢之後,模式空間的内容又列印到标準輸出(第二次)。p
可以使用
-n
參數來抑制第二次的列印行為,
sed -n 'p' quote.txt
執行結果如下,同
sed '' quote.txt
指令結果相同:
-
w
文法
[address] w file
file是要寫入的檔案名,如果檔案名不存在,則會自動建立,如果已經存在,則會覆寫原内容
觀察以下兩條示例:
sed -n 'w books.bak' books.txt
,由于沒有指定位址,那麼會将檔案books.txt的所有内容都寫入到新檔案中。
sed -n '2,3 w junk.txt' books.txt
,将2到3行内容寫到新檔案中
- a
,給最後一行追加内容sed '$a 7) my append txt' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
c
當提供行的位址範圍時,所有行都被作為一組替換成單行文本
sed '2,3c they are changed' books.txt
指令,替換2,3行内容:
- i
,給第一行插入内容,插入到前一行:sed '1i insert txt' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 - l
,首先将books.txt中的空格替換成/tsed 's/ /\t/g' books.txt > junk.txt
,檢視junk.txt檔案的隐藏字元sed -n 'l' junk.txt
此外,shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
指令還能讓文本按照指定的寬度換行:l
,文本中的每一行如果超過40字元,則換行:sed -n 'l 40' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
q
文法
[address]q [value]
隻支援單個位址比對
value作為程式的傳回,可以寫也可不寫
sed '3q 6' books.txt
,比對第三行退出,傳回值6:
- r
指令可以從外部檔案中讀取内容,并在滿足條件的時候顯示r
[address]r file
sed '3r junk.txt' books.txt
,将junk.txt檔案内容在第三行之後顯示:
- e
,執行外部指令date:sed '3e date' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
!
使原來起作用的指令不起作用
:sed '/Paulo/!p' books.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
2.1.2 參數說明
option | 說明 |
---|---|
-n | 抑制輸出 |
-e | 執行多條指令 |
-f | 執行指定腳本檔案裡的指令 |
-
-n
預設情況下,模式空間的内容在處理完畢之後将會列印到标準輸出,該選項用于阻止該行為。
可以檢視
sed '' quote.txt
指令加-n參數和不加參數的情況如下
- -e
使用-e選項,執行多次删除指令,
sed -e '2d;5d' books.txt
- -f
腳本檔案内容如下,即删除第二行和第五行内容:
執行
sed -f testCommand books.txt
指令,結果中删除了第二行和第五行内容,說明指令生效:
2.2 循環和分支
sed提供用于控制執行流的循環和分支語句
2.2.1 循環
sed可以根據标簽(label)跳轉到某一行繼續執行;我們可以定義如下标簽:
:label
:start
:end
:up
定義完标簽之後,如果要跳轉到指定的标簽,使用b指令後跟着标簽名;如果忽略标簽名,sed将會跳轉到sed檔案的結尾。
b start -->表示跳轉到start标簽的位置
-
示例
首先檢視示例檔案books2.txt的内容:
執行以下指令:shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
[email protected]:/opt/shell/sed-demo-master# sed -n '
> h;n;H;x
> s/\n/,/
> /Paulo/!b Print
> s/^/-/
> :Print
> p' books2.txt
結果:
指令分析:
- 第一行
指令,h;n;H;x
是指将目前模式空間中的内容覆寫到保持空間中;h
是用于提前讀取下一行,并覆寫目前模式空間中的這一行;n
将目前模式空間的内容追加到保持空間;H
用于交換模式空間和保持空間中的内容。最終達到的效果就是每次讀取兩行放到模式空間中進行處理。x
- 第二行
指令用于将上面的兩行内容進行處理,把換行符替換成逗号。s/\n/,/
- 第三行
指令,進行比對,如果不滿足比對條件,則跳轉到Print标簽,否則執行第四行指令。/Paulo/!b Print
- 第四行
指令,将這一行的開頭添加s/^/-/
-
- 第五行
隻是一個标簽名:Print
- 第六行
,列印指令;p
不符合比對條件的執行流,過程為
2->3->5->6
;符合比對條件的執行流,
2->3->4->5->6
,兩者差別隻是是否少了第四行指令而已,也就是說,标簽後的内容,都是一樣要執行的。
以上的指令也可以寫在同一行:
sed -n 'h;n;H;x;s/\n/,/;/Paulo/!b Print;s/^/-/;:Print;s/^/!/;p' books2.txt
2.2.2 分支
使用t指令建立分支,隻有目前置條件成功的時候,t指令才會跳轉到該标簽。
前置條件:替換(s)指令執行成功
-
示例
執行指令
sed -n '
> h;n;H;x
> s/\n/,/
> :loop
> /Paulo/s/^/-/
> /----/!t loop
> p' books2.txt
結果:
指令分析(前兩行與以上示例一緻):
- 第三行
,定義了一個loop标簽:loop
- 第四行
,比對存在Paulo的行,如果存在則在開頭添加一個/Paulo/s/^/-/
-
- 第五行
(重點),檢查上面添加/----/!t loop
之後,是否滿足有四個-
,如果不滿足,則跳到第三行,繼續往下執行,再向最前面添加一個-
;如果滿足,則向下執行-
指令。p
是以此示例的前置條件就是第四行指令中的
s
指令執行成功,才會繼續第五行指令。如果第四行指令沒有執行成功,則直接執行最後一行
p
指令。
2.3 行尋址
sed中包含有以下兩種形式的行尋址:
- 以數字形式表示的行區間
- 以文本模式來過濾行
以上兩中方式的文法都相同
[address]command
2.3.1 數字方式行尋址
- 指定某一行,使用單獨的數字
,指定第三行執行sed -n '3d' books.txt
指令d
- 指定行的範圍,起始行和結束行之間用逗号隔開
,第二行到第五行執行sed -n '2,5 p' books.txt
指令p
- $代表檔案最後一行
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
,標明第M行開始的下n行M,+n
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 -
,標明M行開始的每n行M~n
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
2.3.2 文本模式過濾
-
,使用/符号來開啟比對,同時以/符号結束/pattern/command
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式
2.4 多行指令
sed編輯器執行基礎指令時,會基于換行符的位置将資料分成多行,一次處理一行的資料,然後移到下一行重複這個過程。
但是sed編輯器也有用來處理多行文本的特殊指令
指令 | 說明 |
---|---|
N | 将資料流中的下一行追加進來組成多行組一起處理 |
P | 輸出多行文本的模式空間中的第一行 |
2.4.1 N - 加載下一行
sed 'N;s/\n/,/' books2.txt
2.4.2 P - 輸出第一行
sed -n 'N;P' books2.txt
2.5 特殊字元
sed中含有兩個可以用作指令的特殊字元:= 和**&**
2.5.1 =
指令
=
用于輸出行号
sed -n '$n' books2.txt
,輸出最後一行的行号:
三、正規表達式
3.1 定位符
字元 | 說明 |
---|---|
^ | 比對行的開頭 |
$ | 比對行的結尾 |
- ^
sed '/^The/ p' books2.txt
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 - $
sed '/Coelho$/ p' books2.txt
3.2 特殊字元
字元 | 說明 |
---|---|
. | 比對除了換行符以外的所有單個字元 |
- .
$ echo -e 'cat\ndog\nmat\nrats' | sed -n '/..t$/ p'
cat
mat
3.3 字元集相關
符号 | 說明 |
---|---|
[] | 比對字元集 |
[^] | 排除字元集 |
[-] | 比對字元範圍 |
- []
shell三劍客之SED使用一、SED介紹二、使用三、正規表達式 - [^]
,排除出現c或者n字元[^cn]
- [-]
,指出現a到c任一字元[a-c]
3.4 限定符
字元 | 說明 |
---|---|
? | 比對0次到1次 |
+ | 比對一次到多次 |
* | 比對0次到多次 |
{n} | 精确比對n次 |
{n,} | 至少比對n次 |
{n,m} | 比對n-m次 |
3.5 元字元
字元 | 說明 |
---|---|
\s | 比對單個空白内容 |
\S | 比對單個非空白内容 |
\w | 比對單個單詞 |
\W | 比對非單詞 |