1拿撩、sed介紹
?sed 全名為 stream editor衣厘,流編輯器,用程序的方式來編輯文本绷雏,功能相當(dāng)?shù)膹姶笸诽稀J秦悹枌嶒炇业?Lee E.McMahon 在 1973 年到 1974 年之間開發(fā)完成,目前可以在大多數(shù)操作系統(tǒng)中使用涎显,sed 的出現(xiàn)作為 grep 的繼任者坤检。與vim等編輯器不同,sed 是一種非交互式編輯器(即用戶不必參與編輯過程)期吓,它使用預(yù)先設(shè)定好的編輯指令對輸入的文本進行編輯早歇,完成之后再輸出編輯結(jié)構(gòu)。sed 基本上就是在玩正則模式匹配讨勤,所以箭跳,玩sed的人,正則表達(dá)式一般都比較強潭千。
2谱姓、sed工作原理
? ? sed會一次處理一行內(nèi)容。處理時刨晴,把當(dāng)前處理的行存儲在臨時緩沖區(qū)中屉来,成為"模式空間"路翻,接著用sed命令處理緩沖區(qū)中的內(nèi)容,處理完成后茄靠,把緩沖區(qū)的內(nèi)容送往屏幕茂契。接著處理下一行,這樣不斷重復(fù)慨绳,直到文件末尾掉冶。文件內(nèi)容并沒有改變,除非你使用重定向存儲輸出脐雪。
3厌小、正則表達(dá)式概念
? ? 在編寫處理字符串的程序或網(wǎng)頁時,經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需要喂江。正則表達(dá)式就是用于描述這些規(guī)則的工具召锈,換句話說,正則表達(dá)式就是記錄文本規(guī)則的代碼获询。許多程序設(shè)計語言都支持利用正則表達(dá)式進行字符串操作涨岁。在很多文本編輯器里,正則表達(dá)式通常被用來檢索吉嚣、替換那些符合某個模式的文本梢薪。
4、正則表達(dá)式的匹配過程
? ? 簡單描述一下正則表達(dá)式的匹配過程尝哆,就是拿正則表達(dá)式所表示的字符串去和原文字符串內(nèi)容去匹配秉撇,直到匹配到原文內(nèi)容字符串中的一個完整子串就表示匹配成功。舉個例子秋泄,有一行文件內(nèi)容"this is better desk"琐馆,這里用"esk"去匹配,匹配過程是這樣的:首先拿e去匹配文件行內(nèi)容恒序,從this開始瘦麸,直到better的e,第一個字符匹配成功歧胁,接著s去匹配better字符e后邊的t字符滋饲,沒有匹配成功;然后重新拿esk中的e去和better的第二個t去匹配喊巍,沒有成功屠缭,接著原始內(nèi)容的下一個字符,直到desk中的e字符崭参,逐個匹配s呵曹,k字符,到此為止,esk成功匹配奄喂,正則表達(dá)式匹配完畢之剧,整個過程就是這樣,即使再復(fù)雜的正則表達(dá)式的匹配過程也是按照此過程來進行的砍聊。
5、sed語法和常用選項
sed [選項] ‘command’ 文件名稱
選項部分贰军,常見選項包括-n玻蝌,-e,-i词疼,-f俯树,-r選項。
command部分包括:[地址1贰盗,地址2] [函數(shù)] [參數(shù)(標(biāo)記)]
參數(shù)說明:
-e<script>或--expression=<script> 以選項中指定的script來處理輸入的文本文件许饿。
-f<script文件>或--file=<script文件> 以選項中指定的script文件來處理輸入的文本文件。
-h或--help 顯示幫助舵盈。
-n或--quiet或--silent 僅顯示script處理后的結(jié)果陋率。
-V或--version 顯示版本信息。
動作說明:
a :新增秽晚, a 的后面可以接字串瓦糟,而這些字串會在新的一行出現(xiàn)(目前的下一行)~
c :取代, c 的后面可以接字串赴蝇,這些字串可以取代 n1,n2 之間的行菩浙!
d :刪除,因為是刪除啊句伶,所以 d 后面通常不接任何東東劲蜻;
i :插入, i 的后面可以接字串考余,而這些字串會在新的一行出現(xiàn)(目前的上一行)先嬉;
p :打印,亦即將某個選擇的數(shù)據(jù)印出秃殉。通常 p 會與參數(shù) sed -n 一起運行~
s :取代坝初,可以直接進行取代的工作哩!通常這個 s 的動作可以搭配正則表達(dá)式钾军!例如 1,20s/old/new/g 就是啦鳄袍!?
實例
我們先創(chuàng)建一個?testfile?文件,內(nèi)容如下:
$ cat testfile #查看testfile 中的內(nèi)容? HELLO LINUX!? Linux is a free unix-type opterating system.? This is a linux testfile!? Linux test GoogleTaobaoRunoobTesetfileWiki
在?testfile?文件的第四行后添加一行吏恭,并將結(jié)果輸出到標(biāo)準(zhǔn)輸出拗小,在命令行提示符下輸入如下命令:
sed -e 4a\newLine testfile
使用?sed?命令后,輸出結(jié)果如下:
$ sed -e 4a\newLine testfile
HELLO LINUX!? Linux is a free unix-type opterating system.? This is a linux testfile!? Linux test
newLineGoogleTaobaoRunoobTesetfileWiki
以行為單位的新增/刪除
將?testfile?的內(nèi)容列出并且列印行號樱哼,同時哀九,請將第 2~5 行刪除剿配!
$ nl testfile | sed '2,5d'? ? 1? HELLO LINUX!?
? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
sed 的動作為?2,5d,那個?d?是刪除的意思阅束,因為刪除了 2-5 行呼胚,所以顯示的數(shù)據(jù)就沒有 2-5 行了, 另外息裸,原本應(yīng)該是要下達(dá) sed -e 才對蝇更,但沒有 -e 也是可以的,同時也要注意的是呼盆, sed 后面接的動作年扩,請務(wù)必以?'...'?兩個單引號括住喔!
只要刪除第 2 行:
$ nl testfile | sed '2d'
? ? 1? HELLO LINUX!?
? ? 3? This is a linux testfile!?
? ? 4? Linux test
? ? 5? Google? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
要刪除第 3 到最后一行:
$ nl testfile | sed '3,$d'
? ? 1? HELLO LINUX!?
? ? 2? Linux is a free unix-type opterating system.?
在第二行后(即加在第三行) 加上drink tea??字樣:
$ nl testfile | sed '2a drink tea'? ? 1? HELLO LINUX!?
? ? 2? Linux is a free unix-type opterating system.?
drink tea
? ? 3? This is a linux testfile!?
? ? 4? Linux test
? ? 5? Google? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
如果是要在第二行前访圃,命令如下:
$ nl testfile | sed '2i drink tea'
? ? 1? HELLO LINUX!?
drink tea
? ? 2? Linux is a free unix-type opterating system.?
? ? 3? This is a linux testfile!?
? ? 4? Linux test
? ? 5? Google? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
如果是要增加兩行以上厨幻,在第二行后面加入兩行字,例如?Drink tea or .....?與?drink beer?
$ nl testfile | sed '2a Drink tea or ......\
drink beer ?'1? HELLO LINUX!?
? ? 2? Linux is a free unix-type opterating system.? Drink tea or ......drink beer ?? ? 3? This is a linux testfile!?
? ? 4? Linux test
? ? 5? Google? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
每一行之間都必須要以反斜杠?\?來進行新行標(biāo)記腿时。上面的例子中况脆,我們可以發(fā)現(xiàn)在第一行的最后面就有?\?存在。
以行為單位的替換與顯示
將第?2-5?行的內(nèi)容取代成為?No 2-5 number?呢圈匆?
$ nl testfile | sed '2,5c No 2-5 number'? ? 1? HELLO LINUX!? No 2-5 number
? ? 6? Taobao? ? 7? Runoob? ? 8? Tesetfile? ? 9? Wiki
透過這個方法我們就能夠?qū)?shù)據(jù)整行取代了漠另。
僅列出 testfile 文件內(nèi)的第 5-7 行:
$ nl testfile | sed -n '5,7p'? ? 5? Google? ? 6? Taobao? ? 7? Runoob
可以透過這個 sed 的以行為單位的顯示功能, 就能夠?qū)⒛骋粋€文件內(nèi)的某些行號選擇出來顯示跃赚。
數(shù)據(jù)的搜尋并顯示
搜索 testfile 有?oo?關(guān)鍵字的行:
$ nl testfile | sed -n '/oo/p'? ? 5? Google? ? 7? Runoob
如果 root 找到笆搓,除了輸出所有行,還會輸出匹配行纬傲。
數(shù)據(jù)的搜尋并刪除
刪除 testfile 所有包含?oo?的行满败,其他行輸出
$ nl testfile | sed? '/oo/d'? ? 1? HELLO LINUX!?
? ? 2? Linux is a free unix-type opterating system.?
? ? 3? This is a linux testfile!?
? ? 4? Linux test
? ? 6? Taobao? ? 8? Tesetfile? ? 9? Wiki
數(shù)據(jù)的搜尋并執(zhí)行命令
搜索 testfile,找到?oo?對應(yīng)的行叹括,執(zhí)行后面花括號中的一組命令算墨,每個命令之間用分號分隔,這里把?oo?替換為?kk汁雷,再輸出這行:
$ nl testfile | sed -n '/oo/{s/oo/kk/;p;q}'?
? ? 5? Gkkgle
最后的?q?是退出净嘀。
數(shù)據(jù)的查找與替換
除了整行的處理模式之外, sed 還可以用行為單位進行部分?jǐn)?shù)據(jù)的查找與替換<侠讯。
sed 的查找與替換的與?vi?命令類似挖藏,語法格式如下:
sed 's/要被取代的字串/新的字串/g'
將 testfile 文件中每行第一次出現(xiàn)的 oo 用字符串 kk 替換,然后將該文件內(nèi)容輸出到標(biāo)準(zhǔn)輸出:
sed -e 's/oo/kk/' testfile
g?標(biāo)識符表示全局查找替換厢漩,使 sed 對文件中所有符合的字符串都被替換膜眠,修改后內(nèi)容會到標(biāo)準(zhǔn)輸出,不會修改原文件:
sed -e 's/oo/kk/g' testfile
選項?i?使 sed 修改文件:
sed -i 's/oo/kk/g' testfile
批量操作當(dāng)前目錄下以?test?開頭的文件:
sed -i 's/oo/kk/g' ./test*
接下來我們使用 /sbin/ifconfig 查詢 IP:
$ /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:CC:A6:34:84inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0inet6 addr: fe80::290:ccff:fea6:3484/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1.....(以下省略).....
本機的 ip 是 192.168.1.100。
將 IP 前面的部分予以刪除:
$ /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
接下來則是刪除后續(xù)的部分宵膨,即:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0架谎。
將 IP 后面的部分予以刪除:
$ /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'192.168.1.100
多點編輯
一條 sed 命令,刪除 testfile 第三行到末尾的數(shù)據(jù)辟躏,并把 HELLO 替換為 RUNOOB :
$ nl testfile | sed -e '3,$d' -e 's/HELLO/RUNOOB/'? ? 1? RUNOOB LINUX!?
? ? 2? Linux is a free unix-type opterating system.?
-e 表示多點編輯谷扣,第一個編輯命令刪除 testfile 第三行到末尾的數(shù)據(jù),第二條命令搜索 HELLO 替換為 RUNOOB捎琐。
直接修改文件內(nèi)容(危險動作)
sed 可以直接修改文件的內(nèi)容抑钟,不必使用管道命令或數(shù)據(jù)流重導(dǎo)向! 不過野哭,由于這個動作會直接修改到原始的文件,所以請你千萬不要隨便拿系統(tǒng)配置來測試幻件! 我們還是使用文件 regular_express.txt 文件來測試看看吧拨黔!
regular_express.txt 文件內(nèi)容如下:
$ cat regular_express.txt
runoob.google.taobao.facebook.zhihu-weibo-
利用 sed 將 regular_express.txt 內(nèi)每一行結(jié)尾若為 . 則換成 !
$ sed -i 's/\.$/\!/g' regular_express.txt
$ cat regular_express.txt
runoob!google!taobao!facebook!zhihu-weibo-
:q:q
利用 sed 直接在 regular_express.txt 最后一行加入?# This is a test:
$ sed -i '$a # This is a test' regular_express.txt
$ cat regular_express.txt
runoob!google!taobao!facebook!zhihu-weibo-# This is a test
由於 $ 代表的是最后一行,而 a 的動作是新增绰沥,因此該文件最后新增?# This is a test篱蝇!
sed 的?-i?選項可以直接修改文件內(nèi)容,這功能非常有幫助徽曲!舉例來說零截,如果你有一個 100 萬行的文件,你要在第 100 行加某些文字秃臣,此時使用 vim 可能會瘋掉涧衙!因為文件太大了!那怎辦奥此?就利用 sed 盎“ァ!透過 sed 直接修改/取代的功能稚虎,你甚至不需要使用 vim 去修訂撤嫩!
大家快來一起學(xué)習(xí) 文本處理工具sed,缺乏機器練手的小伙伴可以去 cnaaa 看一看蠢终!