Linux高级文本处理之sed(三)
sed高級(jí)命令
sed允許將多行內(nèi)容讀取到模式空間,這樣你就可以匹配跨越多行的內(nèi)容。本篇筆記主要介紹這些命令,它們能夠創(chuàng)建多行模式空間并且處理之。其中,N/D/P這三個(gè)多行命令分別對(duì)應(yīng)于小寫的n/d/p命令,后者我們?cè)谏弦黄呀?jīng)介紹。它們的功能是類似的,區(qū)別在于命令影響的內(nèi)容不同。例如D命令與d命令同樣是刪除模式空間的內(nèi)容,只不過(guò)d命令會(huì)刪除模式空間中所有的內(nèi)容,而D命令僅會(huì)刪除模式空間中的第一行。
一、讀下一行:N
N命令將下一行的內(nèi)容讀取到當(dāng)前模式空間,但是與n命令不一樣的地方是N命令并沒(méi)有直接輸出當(dāng)前模式空間中的行,而是把下一行追加到當(dāng)前模式空間,兩行之間用回車符\n連接,如下圖所示:
說(shuō)明:模式空間包含多行之后,正則表達(dá)式的^/$符號(hào)的意思就變了,^是匹配模式空間的最開始而非行首,$是匹配模式空間的最后位置而非行尾。
實(shí)例1:替換以下文本中的”O(jiān)wner and Operator Guide”為”Installation Guide”
[root@localhost?~]#?cat?text? Consult?Section?3.1?in?the?Owner?and?Operator Guide?for?a?description?of?the?tape?drives available?on?your?system.[root@localhost?~]#?sed?'/Operator$/{N;s/Owner?and?Operator\nGuide/Installation?Guide/}'?text Consult?Section?3.1?in?the?Installation?Guide?for?a?description?of?the?tape?drives available?on?your?system.不過(guò)這個(gè)例子有兩個(gè)局限:
● 我們知道Owner and Operator Guide分割的位置;
● 執(zhí)行替換命令后,前后兩行拼接在一起,導(dǎo)致這行過(guò)長(zhǎng);
第二點(diǎn),可以這樣解決:
[root@localhost?~]#?sed?'/Operator$/{N;s/Owner?and?Operator\nGuide/Installation?Guide\n/}'?text Consult?Section?3.1?in?the?Installation?Guidefor?a?description?of?the?tape?drives available?on?your?system.實(shí)例2:Owener and Operator Guide出現(xiàn)在多行的多個(gè)位置
[root@localhost?~]#?cat?text???#原文文本 Consult?Section?3.1?in?the?Owner?and?Operator Guide?for?a?description?of?the?tape?drives available?on?your?system.Look?in?the?Owner?and?Operator?Guide?shipped?with?your?system.Two?manuals?are?provided?including?the?Owner?and Operator?Guide?and?the?User?Guide.The?Owner?and?Operator?Guide?is?shipped?with?your?system.[root@localhost?~]#?sed?'s/Owner?and?Operator?Guide/Installation?Guide/ >??/Owner/{ >??N >??s/?*\n/?/ >??s/Owner?and?Operator?Guide?*/Installation?Guide\ >??/ >?}'?text Consult?Section?3.1?in?the?Installation?Guidefor?a?description?of?the?tape?drives available?on?your?system.Look?in?the?Installation?Guide?shipped?with?your?system.Two?manuals?are?provided?including?the?Installation?Guideand?the?User?Guide.The?Installation?Guide?is?shipped?with?your?system.說(shuō)明:這里我們首先將在單行出現(xiàn)的Owner and Operator Guide替換為Installation Guide,然后再尋找匹配Owner的行,匹配后讀取下一行的內(nèi)容到模式空間,并且將中間的換行符替換成空格,最后再替換Owner and Operator Guide。
看上去sed命令中作了兩次替換是多余的。實(shí)際上,如果去掉第一次替換,再運(yùn)行腳本,就會(huì)發(fā)現(xiàn)輸出存在兩個(gè)問(wèn)題。一個(gè)是結(jié)果中最后一行不會(huì)被替換(在某些版本的sed中甚至不會(huì)被輸出)。這是因?yàn)樽詈笠恍衅ヅ淞?#34;Owner",執(zhí)行N命令,但是已經(jīng)到了文件末尾,某些版本就會(huì)直接打印這行再退出,而另外一些版本則是不作出打印立即退出。對(duì)于這個(gè)問(wèn)題可以通過(guò)命令"$!N"來(lái)解決。這表示N命令對(duì)最后一行不起作用。另外一個(gè)問(wèn)題是"look manuals"一段被拆為兩行,而且與下一段的空行被刪除了。這是因?yàn)閮?nèi)嵌的換行符被替換的結(jié)果。因此,sed中做兩次替換一點(diǎn)也不是多余的。
二、刪除行:D
該命令刪除模式空間中第一行的內(nèi)容,而它對(duì)應(yīng)的小d命令刪除模式空間的所有內(nèi)容。D不會(huì)導(dǎo)致讀入新行,相反它會(huì)回到最初的編輯命令,重要應(yīng)用在模式空間剩余的內(nèi)容上。
實(shí)例1:現(xiàn)在我們要?jiǎng)h除文件text多余的空行,將多個(gè)空行縮減成一行。
文件內(nèi)容:
[root@localhost?~]#?cat?text? This?line?is?followed?by?1?blank?line.This?line?is?followed?by?2?blank?line.This?line?is?followed?by?3?blank?line.This?line?is?followed?by?4?blank?line.This?is?the?end.使用d命令刪除如下:
[root@localhost?~]#?sed?'/^$/{N;/^\n$/d}'?text? This?line?is?followed?by?1?blank?line.This?line?is?followed?by?2?blank?line. This?line?is?followed?by?3?blank?line.This?line?is?followed?by?4?blank?line. This?is?the?end.說(shuō)明:我們會(huì)發(fā)現(xiàn)一個(gè)奇怪的結(jié)果,奇數(shù)個(gè)數(shù)的相連空行已經(jīng)被合并成一行,但是偶數(shù)個(gè)數(shù)的卻全部被刪除了。造成這樣的原因需要重新翻譯下上面的命令,當(dāng)匹配一個(gè)空行是,將下一行也讀取到模式空間,然后若下一行也是空行,則模式空間中的內(nèi)容應(yīng)該是\n,因此匹配^\n$,從而執(zhí)行d命令會(huì)將模式空間中的內(nèi)容清空,結(jié)果就是相連的兩個(gè)空行都被刪除。這樣就可以理解為什么相連奇數(shù)個(gè)空行的情況下是正常的,而偶數(shù)個(gè)數(shù)就有問(wèn)題了。
使用D命令刪除如下:
[root@localhost?~]#?sed?'/^$/{N;/^\n$/D}'?text? This?line?is?followed?by?1?blank?line.This?line?is?followed?by?2?blank?line.This?line?is?followed?by?3?blank?line.This?line?is?followed?by?4?blank?line.This?is?the?end.說(shuō)明:D命令只會(huì)刪除模式空間的第一行,而且刪除后會(huì)重新在模式空間的內(nèi)容上執(zhí)行編輯命令,類似形成一個(gè)循環(huán),前提是相連的都是空行。當(dāng)匹配一個(gè)空行時(shí),N讀取下一行內(nèi)容,此時(shí)匹配^\n$導(dǎo)致模式空間中的第一行被刪除。現(xiàn)在模式空間中的內(nèi)容是空的,重新執(zhí)行編輯命令,此時(shí)匹配/^$/。繼續(xù)讀取下一行,當(dāng)下一行依然為空行時(shí),重復(fù)之前的動(dòng)作,否則輸出當(dāng)前模式空間的內(nèi)容。造成的結(jié)果是連續(xù)多個(gè)空行,只有最后一個(gè)空行是保留輸出的,其余的都被刪除了。這樣的結(jié)果才是我們最初希望得到的。
三、打印行:P
P命令與p命令一樣是打印模式空間的內(nèi)容,不同的是前者僅打印模式空間的第一行內(nèi)容,而后者是打印所有的內(nèi)容。因?yàn)榫庉嬅钊繄?zhí)行完之后,sed默認(rèn)會(huì)輸出模式空間的內(nèi)容,所以一般情況下,p和P命令都是與-n選項(xiàng)一起使用的。但是有一種情況是例外的,即編輯命令的執(zhí)行流程被改變的情況,例如N,D等。很多情況下,P命令都是用在N命令之后,D命令之前的。這三個(gè)命令合起來(lái),可以形成一人輸入輸出的循環(huán),并且每次只打印一行:讀入一行后,N繼續(xù)讀下一行,P命令打印第一行,D命令刪除第一行,執(zhí)行流程回到最開始重復(fù)該過(guò)程。
實(shí)例1:
[root@localhost?~]#?echo?-e?"line1nline2nline3"?|?sed?'$!N;P;D' line1nline2nline3 [root@localhost?~]#?echo?-e?"line1\nline2\nline3"?|?sed?'$!N;P;D' line1 line2 line3實(shí)例2:
[root@localhost?~]#?echo?-e?"line1\nline2\nline3"?|?sed?-n?'N;1P'說(shuō)明:你可能期望打印第一行的內(nèi)容,事實(shí)上并沒(méi)有輸出。原因是當(dāng)N繼續(xù)讀入第二行后,當(dāng)前行號(hào)已經(jīng)是2了,行號(hào)只是sed在內(nèi)部維護(hù)的一個(gè)計(jì)數(shù)變量而已,每當(dāng)讀入新的一行,行號(hào)就加一。
實(shí)例3:
[root@localhost?~]#?echo?-e?"line1\nline2\nline3"?|?sed?-n?'$!N;=' 2 3實(shí)例4:N/P/D三個(gè)命令是如何配合使用
[root@localhost?~]#?cat?-n?f11??The?UNIX2??System?and?UNIX3??...[root@localhost?~]#?sed?'/UNIX$/{N;s/\nSystem/?Operating?&/;P;D}'?f1 The?UNIX?Operating? System?and?UNIX ...實(shí)例4執(zhí)行流程圖:
轉(zhuǎn)載于:https://blog.51cto.com/yolynn/1890096
總結(jié)
以上是生活随笔為你收集整理的Linux高级文本处理之sed(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 根据IP地址查询其所属城市
- 下一篇: Linux内存管理和分析vmalloc使