Unix & Linux的文本處理工具
當大家看到標題時腦中閃過的大概是鋪天蓋地baidu,google出來的冗餘的各類使用介紹,老生常談希望能讓大家對這三個文本工具有新的理解。
1、grep
grep不做過多的介紹, 列印出匹配的行, 著重點在於輸出結果並不對文本本身做修改。
有個關於grep的小故事, 從sed和grep能追溯到最初的unix行編輯器ed而grep的命名代表g(全局)/re(正則表達式)/p(列印)正是ed中全局列印行匹配的語法. grep自身的劣勢在於無法實現多行匹配,這時sed和awk相繼出現彌補了grep的不足。
2、sed和awk的比較
在進入sed的相關討論之前,先就sed跟awk之間進行簡單的比較。
Advertisements
1. 相似性
可使用指定的腳本文件對相應文本進行編輯。
sed -f 'script filename' or stdin
awk -f 'script filename' or stdin
默認全局匹配並且擁有自身的主輸入循環。
除去影響控制流的命令或語句(sed中: t,b;awk中continue,break等)默認對文本的每一讀取的行依次執行相應的命令或語句。
2. 優劣性
awk相較於文本編輯工具更像是一門語言,awk條件、循環、判斷語句有顯性的標識(if,while,for...);而sed只存在單一的判斷邏輯(參考blabel,t label)。
(採用nginx的配置文件格式)
Advertisements
取出upstream awk_test對應的配置塊:
Solution1:
Solution2:
相較之下Solution 2不需要複雜的判斷,只需通過定址來匹配並列印相應的文本;Solution1更適合於進行多行匹配並替換。另一方面,Solution1中sed通過創建多行空間模式並輸出,而awk通過修改記錄分隔符來實現多行匹配的不同。
awk擁有系統變數(FS,RS,OFS,ORS...)、內置函數、數組數據結構、傳參(-vvar=value)、引用系統命令(通過system() getline() close()函數)等。
(點擊查看大圖)
awk除去主輸入循環還存在BEGIN和END過程,用於某些在處理輸入之前或者處理輸入完成之後的操作。
sed也有過人之處,如果對sed的工作模式進行深入了解,會發現有一個叫做保持空間(holdspace)的東西,下圖大體描述了sed的工作模式,並且闡述了模式空間(pattern space)跟保持空間(holdspace)之間的聯繫。模式空間跟保持空間中的內容可進行刪除,交換等。
sed的指令集都是單一的字母,並且有option可直接修改文件。而awk可能需要指定內置變數的值,或是通過輸出重定向保存為新的文件。
結語
綜上所述:
grep適用於單行匹配列印的場景;
sed適用於多行模式的替換的場景;
awk適合更多的邏輯表達式並輸出的場景。
但三個命令都需要文本格式統一化的大前提,對於一個文本中的多種格式,可以先將同一種格式的內容整理到文件中,再將其他格式再分別整理到新的文件中。
統一文本格式固然重要,能準確匹配意圖的正則表達式也必不可少,這也是大家頭疼的部分。如若有機會,我會再跟大家介紹文本匹配中磨人的小妖精——正則表達式。它在不同的命令中、語言中支持不同的標準,更易於與Unix-like系統的fileglobbing混淆,常常讓人咬牙切齒,欲罷不能。
本文作者:王嚴(點融黑幫),隸屬於點融Infra團隊的devops組的運維攻城獅,歡迎各種姿勢交流。
本文由@點融黑幫(ID:DianrongMafia)原創發佈於今日頭條,未經許可,禁止轉載。