sed Stream Editor
sed 是一個文件編輯工具,把所有文件加載到內存的緩存區中,按換行符進行讀取,一次從緩存區中讀取一行到自己的內部空間,並完成編輯,並將結果輸出到屏幕上,默認sed不會對原文件進行更改。
sed 使用格式:
sed [options] 'addr1[,addr2]編輯命令' FILE ... sed [options] “addr1[,addr2]編輯命令” FILE ... \\ 當有變量替換時,使用雙引號
常用選項(options):
-n:靜默模式,不輸出模式空間中的內容;
-r:擴展的正則表達式
-f /path/to/sed_script_file:指定sed腳本文件
-e 'script' -e 'script':指定多個編輯指令
-i:直接編輯原文件
編輯命令:
d: 刪除
p: 打印
sed -n '/^#/,/^\//p' /etc/fstab \\ 如果不用選項n會把模式空間的內容也一併輸出
i \text:
# sed '/^#/i \begin' test.txt \\ 在每個#號開頭的行前插入一行begin
a \text: 後面
r /path/to/somefile: 在指定位置把另外一個文件的內容插入進來
w /path/to/somefile:將符合條件的所有行保存至指定的文件中
=:顯示符合條件的行的行號
sed -n '/^\//=' /etc/fstab
y:字符轉換
sed '/^#/y/abcdefg/ABCDEFG/' test.txt
s///: 查找條件可以使用模式,但要替換的內容不行
地址定界:
number:指定輸入文件的唯一行.
startline,endline:指定開始行和結束的行如:1,5表示從1行開始到第五行結束。
/pat1/,/pat2/ :第一個被模式匹配到的行到,最後一個被模式匹配到的行
# sed -n '/^#/,/[[:digit:]]/p' test.txt
/pattern/ :被模式匹配到的行,中間包含正則表達式,如果中間爲空則匹配最近一次正則表達式。
addr1,+N:匹配地址1以及後面的N行內容,如3,+4,表示從3行開始及後面4行的內容。
# sed '3,+4d' test.txt
\cpatternc:\c與c之間匹配擴展正則表達式,c字符可以是任意字符。
部份指令詳解:
查找替換s,格式如下
# sed '[address]s/pattern/replacement/flags'
address爲地址定界,省略代表全文搜索。
s爲替換指定
pattern爲匹配的模式
replacement 爲需要替換的內容
flags爲標記,g 爲全局替換,p打印模式空間中的內容,i: ignore-case,不區分字符大小寫
示例:
如果一個指定過長,這時有必要使用-f選項指定sed腳本文件,在腳本文件中可以包含多行指令來對文件進行修改
原文件:
DEVICE=eth0
TYPE=Ethernet
ONBOOT=no
NM_CONTROLLED=yes
BOOTPROTO=none
NETMASK=255.255.255.0
gateway=192.168.0.1
DNS1=114.114.114.114
腳本
/.*/{
/ONBOOT/c ONBOOT=yes \\ 替換
/NETMASK/i IPADDR=192.168.0.29 \\ 插入
/gateway/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ \\ 轉換
}
執行結果
# sed -f sed.sh ifcfg-eth0 DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=none IPADDR=192.168.0.29 NETMASK=255.255.255.0 GATEWAY=192.168.0.1 DNS1=114.114.114.114
2、匹配以UUID開頭的行,把/etc/issue中的內容讀取到匹配到的內容後面
# sed '/^UUID/r /etc/issue' /etc/fstab
3、將匹配到的行保存至/tmp/filetable.txt,是覆蓋式添加的
# sed '/^\//w /tmp/filetable.txt' /etc/fstab
4、有如下內容文件
He like his liker.
He like his lover.
She love her liker.
She love her lover.
(1)、刪除以上內容當中包含單詞“l..e”前後一致的行;
# sed '/\(l..e\).*\1/d' test
(2)、將文件中“l..e”前後一致的行中,最後一個l..e詞首的l換成大寫L;
# sed 's/\(\(l\(..e\)\).*\)\2/\1L\3/g' test
練習:
1、替換/etc/inittab文件中“id:3:initdefault:”一行中的數字爲5;
# sed 's@\(id:\)[0-9]\(:initdefault\)@\15\2@' /etc/inittab
2、刪除/etc/init.d/funcions文件中的空白行;
# sed '/^$/d' /etc/ini.t/functions
3、刪除/etc/inittab文件中位於行首的#;
# sed 's@^#@@g' /etc/initta
4、刪除/etc/rc.d/rc.sysinit文件中以#後跟至少一個空白字符開頭的行的行首的#和空白字符;
# sed 's@^#[[:space:]]\{1,\}@@g' /etc/rc.d/rc.sysinit
5、刪除/boot/grub/grub.conf文件中行首的空白字符;
# sed 's@^[[:space:]]\{1,\}@@' /boot/grub/grub.conf
6、取出一個文件路徑的目錄名稱,如/etc/sysconfig/network,其目錄爲/etc/sysconfig,功能類似dirname命令;
# echo /etc/sysconfig/network-scripts/ifcfg-eth0/ | sed 's@[^/]\{1,\}/*$@@'
意思找最後一個以/開頭的字符串,後面跟着可有可無的/替換成什麼也沒有