Sed and awk 筆記之 sed 篇:簡單介紹

最近在閱讀《sed & awk》,這本書是sed和awk相關書籍中比較經典的一本。我在讀書的時候有一個習慣,就是會作一些筆記,如果有條件我會放到博客中。寫博客不僅是給別人看的,更是寫給自己看的,同時因為寫給別人看,所以必然會在一些細節的地方寫得很清楚明了,可以加深自己對原書的理解,同時以后回頭看的時候,我自己也能快速的回憶起來。

另外一方面,我會選擇英文原版來閱讀而非中文翻譯版,主要是出于英文版的內容更加準確、容易領會作者的本意這個方面的原因。畢竟翻譯的內容一方面因為翻譯的時候會丟失一些原版的意思,同時因為不同的人有不同的理解,在翻譯中可能會夾雜著自己個人的理解。就好比這一系列的文章,許多內容都是出自原書,我只不過是翻譯了些內容加了點注解而已,所心也只能稱之為筆記。

文中對一些術語的翻譯只是按本人自己的喜好而定,請見諒。

本系列包含兩部分的內容:sed篇和awk篇。

sed篇總共分成6章:

Sed&awk筆記之sed篇:簡單介紹

Sed&awk筆記之sed篇:模式空間與地址匹配

Sed&awk筆記之sed篇:sed基礎命令

Sed&awk筆記之sed篇:高級命令(一)

Sed&awk筆記之sed篇:高級命令(二)

Sed&awk筆記之sed篇:實戰

sed篇總共分成6章:(簡書版)

Sed&awk筆記之sed篇:簡單介紹

Sed&awk筆記之sed篇:模式空間與地址匹配

Sed&awk筆記之sed篇:sed基礎命令

Sed&awk筆記之sed篇:高級命令(一)

Sed&awk筆記之sed篇:高級命令(二)

Sed&awk筆記之sed篇:實戰

awk篇暫時還未計劃。

Sed&awk筆記之awk篇:快速了解Awk(一)

Sed&awk筆記之awk篇:快速了解Awk(二)

Sed&awk筆記之awk篇:快速了解Awk(三)

Sed是什么

《sed and awk》一書中(1.2 A Stream Editor)是這樣解釋的:

Sed is a "non-interactive" stream-oriented editor. It is stream-oriented because, like many UNIX

programs, input flows through the program and is directed to standard output.

Sed本質上是一個編輯器,但是它是非交互式的,這點與VIM不同;同時它又是面向字符流的,輸入的字符流經過Sed的處理后輸出。這兩個特性使得Sed成為命令行下面非常有用的一個處理工具。

如果對sed的歷史有興趣,可以看書中2.1節"Awk, by Sed and Grep, out of Ed",這里就不多介紹。

基本概念

sed命令的語法如下所示:

sed [options] script filename

同大多數Linux命令一樣,sed也是從stdin中讀取輸入,并且將輸出寫到stdout,但是當filename被指定時,則會從指定的文件中獲取輸入,輸出可以重定向到文件中,但是需要注意的是,該文件絕對不能與輸入的文件相同。

options是指sed的命令行參數,這一塊并不是重點,參數也不多。

script是指需要對輸入執行的一個或者多個操作指令(instruction),sed會依次讀取輸入文件的每一行到緩存中并應用script中指定的操作指令,因此而帶來的變化并不會影響最初的文件(注:如果使用sed時指定-i參數則會影響最初的文件)。如果操作指令很多,為了不影響可讀性,可以將其寫到文件中,并通過-f參數指定scriptfile:

sed -f scriptfile filename

這里有一個建議,在命令行中指定的操作指令最好用單引號引起來,這樣可以避免shell對特殊字符的處理(如空格、$等,關于這一點可以參考簡潔的Bash編程技巧續篇 - 9. 引號之間的區別)。這個建議同樣適用grep/awk等命令,當然如果有時候確實不適合使用單引號時,記得對特殊字符轉義。

無論是將操作指令通過命令行指定,還是寫入到文件中作為一個sed腳本,必須包含至少一個指令,否則用sed就沒有意義了。一般會同時指定多個操作指令,這時候指令之間的順序就顯得非常重要。而你的腦海中必須有這么一個概念,即每個指令應用后,當前輸入的行會變成什么樣子。要做到這一點首先必須要了解sed的工作原理,要做到“知其然,且知其所以然”。

每條操作指令由pattern和procedure兩部分組成,pattern一般是用'/'分隔的正則表達式(在sed中也有可能是行號,具體參見Sed命令地址匹配問題總結),而procedure則是一連串編輯命令(action)。

sed的處理流程,簡化后是這樣的:

讀入新的一行內容到緩存空間;

從指定的操作指令中取出第一條指令,判斷是否匹配pattern;

如果不匹配,則忽略后續的編輯命令,回到第2步繼續取出下一條指令;

如果匹配,則針對緩存的行執行后續的編輯命令;完成后,回到第2步繼續取出下一條指令;

當所有指令都應用之后,輸出緩存行的內容;回到第1步繼續讀入下一行內容;

當所有行都處理完之后,結束;

具體流程見下圖:

簡單例子

概念如果脫離實際的例子就會顯得非常枯燥無趣,這本書在這一點上處理得很好,都是配上實際的例子來講解的。不過有點遺憾的是,書中的例子大多是與troff macro有關的,我們很難有條件來實際測試例子,在筆記中我會盡量使用更加淺顯易懂的例子來說明。

下面是摘自書中的一個例子,假設有個文件list:

John Daggett, 341 King Road, Plymouth MA

Alice Ford, 22 East Broadway, Richmond VA

Orville Thomas, 11345 Oak Bridge Road, Tulsa OK

Terry Kalkas, 402 Lans Road, Beaver Falls PA

Eric Adams, 20 Post Road, Sudbury MA

Hubert Sims, 328A Brook Road, Roanoke VA

Amy Wilde, 334 Bayshore Pkwy, Mountain View CA

Sal Carpenter, 73 6th Street, Boston MA

這個例子中用到的知識點都會在后文中介紹,你可以先知道有這個東西就行。

假如,現在打算將MA替換成Massachusetts,可以使用替換命令s:

$ sed-e's/MA/Massachusetts/'listJohnDaggett,341KingRoad,PlymouthMassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,SudburyMassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,BostonMassachusetts

這里面的-e選項是可選的,這個參數只是在命令行中同時指定多個操作指令時才需要用到,如:

$ sed-e's/ MA/, Massachusetts/'-e's/ PA/, Pennsylvania/'listJohnDaggett,341KingRoad,Plymouth,MassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFalls,PennsylvaniaEricAdams,20PostRoad,Sudbury,MassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,Boston,Massachusetts

即使在多個操作指令的情況下,-e參數也不是必需的,我一般不會加-e參數,比如上面的例子可以換成下面的寫法:

$ sed's/ MA/, Massachusetts/;s/ PA/, Pennsylvania/'list

操作指令之間可以用分號分隔,這點和shell命令可以用分號分隔是一樣的。

這里提前說一點使用s替換命令需要小心的地方,不要忘記結尾的斜杠,如果你遇到下面的錯誤說明你犯了這個錯誤:

$ sed-e's/ MA/, Massachusetts'list

sed:-e expression#1, char 21: unterminated `s' command

假如這時,我只想輸出替換命令影響的行,而不想輸出文件的所有內容,需要怎么辦?這個時候可以利用替換命令s的p選項,它會將替換后的內容打印到標準輸出。但是僅僅這樣是不夠的,否則輸出的結果并非我們所想要的:

$ sed-e's/ MA/, Massachusetts/p'listJohnDaggett,341KingRoad,Plymouth,MassachusettsJohnDaggett,341KingRoad,Plymouth,MassachusettsAliceFord,22EastBroadway,RichmondVAOrvilleThomas,11345OakBridgeRoad,TulsaOKTerryKalkas,402LansRoad,BeaverFallsPAEricAdams,20PostRoad,Sudbury,MassachusettsEricAdams,20PostRoad,Sudbury,MassachusettsHubertSims,328ABrookRoad,RoanokeVAAmyWilde,334BayshorePkwy,MountainViewCASalCarpenter,736thStreet,Boston,MassachusettsSalCarpenter,736thStreet,Boston,Massachusetts

從上面可以看出,文件的所有行都被打印到標準輸出,并且被替換命令修改的行輸出了兩遍。造成這個問題的原因是,sed命令應用完所有指定之后默認會將當前行打印輸出,所以就有了上面的結果。解決方法是在使用sed命令是指定-n參數,該參數會抑制sed默認的輸出:

$ sed-n's/ MA/, Massachusetts/p'listJohnDaggett,341KingRoad,Plymouth,MassachusettsEricAdams,20PostRoad,Sudbury,MassachusettsSalCarpenter,736thStreet,Boston,Massachusetts

正則表達式

書中的第3章的內容都是介紹正則表達式,這是因為sed的很多地方都需要用到正則表達式,比如操作指令的pattern部分以及替換命令中用到的匹配部分。關于正則這部分可以看Linux/Unix工具與正則表達式的POSIX規范,文章中已經講得非常清楚了,我自已在忘記一些內容的時候也是去查閱這篇文章。

由于篇幅限制,本篇就到此為止,下一篇見Sed&awk筆記之sed篇:模式空間與地址匹配

轉自:團子的小窩, 本文固定鏈接:Sed and awk 筆記之 sed 篇:簡單介紹

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容