流編輯器Sed

Sed簡介

Sed是一款流編輯工具,用來對文本進行過濾與替換操做,特別是當你想要對幾十個配置文件作統一修改時,你會感覺到Sed的魅力!Sed經過一次僅讀取一行內容來對某些指令進行處理後輸出,因此Sed更適合於處理大數據文件。首先,Sed經過文件或管道讀取文件內容,但Sed默認並不直接修改源文件,而是將讀入的內容複製到緩衝區中,咱們稱之爲模式空間(pattern space),全部的指令操做都是在模式空間中進行的,而後Sed根據相應的指令對模式空間中的內容進行處理並輸出結果,默認輸出至標準輸出(即屏幕上)。Sed工做流程以下圖所示:正則表達式

Sed基本語法格式

Sed從文件中讀取數據,若是沒有輸入文件,則默認對標準輸入進程數據進行處理,腳本指令是第一個非「-」開頭的參數,具體語法格式以下。緩存

用法:sed[選項]...{腳本指令} [輸入文件]...
選項:--version          顯示sed版本
   -h或--help          顯示幫助文檔
   -n或--quiet或--silent  靜默輸出,默認狀況下,sed程序在全部的腳本指令執行完畢後,將自動打印模式空間中的內容,該選項能夠屏蔽自動打印app

   -e script       容許多個腳本指令被執行
   -f script-file      從文件中讀取腳本指令,對編寫自動腳本程序很實用
   -i或-in-place     慎用,該選項將直接修改源文件
   -l N          該選項指定l指令能夠輸出的行長度,l指令爲輸出非打印字符
   --posix       禁用GNU sed擴展功能
   -r           在腳本指令中使用擴展正則表達式
   -s或--separate    默認狀況下,sed將把輸入的多個文件名做爲一個長的連續的輸入流。而GNU sed則容許把它們看成單獨的文件
   -u或-unbuffered  最低限度的緩存輸入與輸出運維

Sed 入門範例

1. 基本格式範例

Sed 經過特定的腳本指令對文件進行處理,這裏就簡單介紹幾個腳本指令操做做爲Sed程序的範例。a,append表示追加指令;i,insert表示插入指令;d,delete表示刪除指令;s,substitution表示替換指令。sed腳本指令的基本格式是:[地址]命令(有些命令僅能夠對一行操做,有些能夠對多行操做),命令也能夠用花括號進行組合,使命令序列能夠做用於同一個地址。工具

address {
command1
command2
command3
}測試

下面的test.txt爲操做樣本源文件(注意有若干空白行),介紹Sed的用法。大數據

[root@192 ~]# cat test.txt
DEVICE=ens33
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254ui

ONBOOT=yesspa

[root@192 ~]# sed '2a TYPE=Ethernet' test.txt     # 第二行後追加TYPE=Ethernet命令行

[root@192 ~]# sed '3i TYPE=Ethernet' test.txt      # 第三行前追加TYPE=Ethernet 

[root@192 ~]# sed 's/yes/no/g' test.txt                # 將樣本文件中的全部yes替換爲no 

[root@192 ~]# sed '3,4d' test.txt                           # 刪除第3,4行的內容

[root@192 ~]# sed -e '3,4d' test.txt                       # 刪除第3,4行的內容

注意:這裏 sed -e 和 sed 是同樣的!同時也要注意的是,sed 後面接的動做,請務必以 '' 兩個單引號括住!

以上大多數操做指令都依據行號定位操做對象(地址),如:2a即第二行後追加。

實際工做中,可能大多數狀況你並不肯定你要操做對象(地址)的行號,這時更多的會使用正則表達式肯定操做對象(地址)。下面是使用正則表達式定位操做行的示例:

匹配到包含ONBOOT的行,並在其後添加TYPE=Ethernet:

[root@192 ~]# sed '/ONBOOT/a TYPE=Ethernet' test.txt

匹配以GATEWAY開始的行,並刪除該行:

[root@192 ~]# sed '/^GATEWAY/d' test.txt

另外,咱們的操做指令能夠寫入到腳本文件中,並經過sed的-f選項讀取,腳本文件中的註釋行是以#開始的行,若是#後面的字符爲n,則屏蔽Sed程序的自動輸出功能,等同於命令選項-n。

建立一個sed腳本,內容以下:

[root@192 ~]# cat sed.sh      # 腳本內容爲匹配到空白行後,刪除該行
# This is a test sed command
/^$/d

[root@192 ~]# sed -f sed.sh test.txt      # 對test.txt文件執行sed.sh腳本指令

而當你須要執行多個指令時,可使用如下三種方法:

[root@192 ~]# sed 's/yes/no/; s/static/dhcp/' test.txt       # 使用分號隔開指令

[root@192 ~]# sed -e 's/yes/no/' -e 's/static/dhcp/' test.txt      # 使用-e選項

[root@192 ~]# sed '            # 利用分行
> s/yes/no/
> s/static/dhcp/' test.txt

然而在命令行上輸入過長的指令是愚蠢的,這時須要使用-f選項指定sed 腳本文件,在腳本文件中能夠包含多行指令,並且也便於修改。

2. 操做地址匹配範例

經過以上範例不難發現,咱們編寫的腳本指令須要指定一個地址來決定操做範圍,若是不指定,則默認對文件的全部行進行操做。如:sed 'd' test.txt將刪除test.txt的全部行,而'2d'則僅刪除第二行。Sed爲咱們提供瞭如下這些方式來肯定須要操做地址的範圍。

number       指定輸入文件的惟一行號

first~step      指定以first開始,並指定操做步長爲step,如一、2指定第一行、第三行、第五行……爲操做地址。2~5指定第二行開始,每5行匹配一次操做地址

[root@192 ~]# sed -n '1~2p' test.txt  # 打印文件的奇數行

$          匹配文件的最後一行

/regexp/       //中間包含的是正則表達式,經過正則表達式匹配操做地址。若是//中正則表達式爲空,匹配最近一次正則表達式的匹配地址

\cregexpc      \c與c之間匹配擴展正則表達式,c字符可使用任意字符替代

addr1,addr2    匹配從操做地址1到操做地址2的全部行

[root@192 ~]# sed '2,8d' test.txt  # 刪除2~8之間的全部行

addr1,+N     匹配地址1以及後面的N行內容

Sed指令與腳本

1. Sed經常使用指令彙總

下表給出了經常使用的sed腳本指令的說明,下面分別看看每一個指令的詳細用法。

指令 功能 指令 功能
s 替換 d 刪除
a 追加 i 插入
c 更改 l 打印(顯示非打印字符)
y 按字符轉換 L 打印(不顯示非打印字符)
p 打印 r 讀入文件內容
w 保存至文件 q 退出

2. Sed腳本指令範例

範例1

範例1所使用的樣本文件爲(注意有空白行):

[root@192 ~]# cat test.txt
DEVICE=ens33
ONBOOT=yes
BOOTPROTO=static

IPADDR=192.168.0.1
NETMASK=255.255.255.0

GATEWAY=192.168.0.254

範例1:刪除文件中空白行

編寫sed腳本爲:

[root@192 ~]# cat sed.sh
/.*/{
/^$/d
}

執行sed程序的結果以下:

[root@192 ~]# sed -f sed.sh test.txt
DEVICE=ens33
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.254

範例2~範例5所使用的樣本文件爲:

[root@192 ~]# cat test.txt
DEVICE=ens33
ONBOOT=yes
BOOTPROTO=static
NETMASK=255.255.255.0
GATEWAY=192.168.0.254

範例2:在static行後添加一行,內容爲IPADDR=192.168.0.1

[root@192 ~]# sed '/static/a IPADDR=192.168.0.1' test.txt

範例3:在匹配NETMASK的行前插入內容IPADDR=192.168.0.1

[root@192 ~]# sed '/NETMASK/i IPADDR=192.168.0.1' test.txt

範例4:將包含ONBOOT行的內容更改成ONBOOT=no

[root@192 ~]# sed '/ONBOOT/c ONBOOT=no' test.txt

範例5:列印(l)顯示模式空間中的內容,顯示非打印字符,通常與-n一塊兒使用,不然會輸出兩次

[root@192 ~]# sed -n '1,2l' test.txt    # 在sed腳本文件中,須要#n屏蔽自動輸出

結果以下:

DEVICE=ens33$
ONBOOT=yes$

範例6:顯示第1、二行的內容

打印(p):做用相似於l(列印),但不顯示非顯示字符,通常與-n配合使用

[root@192 ~]# sed -n '1,2p' test.txt

結果以下:
DEVICE=ens33
ONBOOT=yes

範例7:顯示test.txt內容的前兩行內容後退出sed指令

[root@192 ~]# sed '2q' test.txt

範例8:直接修改文件內容(危險動做)

注意:sed -i 能夠直接修改文件的內容,沒必要使用管道命令或重定向! 不過,因爲這個動做會直接修改到原始的文件,因此請你千萬不要隨便拿系統配置來測試!

 [root@192 ~]# sed -i 's/yes/no/' test.txt

範例9:在test.txt最後一行加入# This is a test!

[root@192 ~]# sed -i '$a # This is a test!' test.txt

 

參考自,丁明一    編著    《Linux運維之道》

相關文章
相關標籤/搜索