標籤:
sed工具全稱為流式編輯器,它可以被使用作為行過濾器(顧名思義sed是按照行尋找進行操作的),它的工作原理可以描述為:把前一個程式的輸出引入到sed的輸入,經過一系列編輯命令轉換為另外一種格式輸出。(形象的解釋如所示,模式空間會在後面單獨提出)
以前學習到grep預設是在Basic模式下工作,這裡的sed工具如grep一般,也是預設在Basic模式下工作,sed也支援Regex的使用,使用Regex是在"/"之間的模式。(當然這裡的分隔字元不是非"/"不可,也各可以自己定義)
1.^:行首定位器(如/^aa/匹配以aa開頭的行)
2.$:行尾定位器(如/aa$/匹配以aa結尾的行)
3. .:匹配除分行符號以外的單個字元(當然.. 就表示匹配兩個字元了)
......(還有很多可以查看上一篇的grep的使用,有詳細的介紹Regex的構成)
下面就以例子來介紹sed的使用。
1.文法:
sed編輯命令的基本格式為:/pattern/action/(其中pattern為Regex,action是使用的編輯操作)
這個操作可以比較形象的解釋為:通過sed一行一行的讀出待處理檔案,如果某一行與pattern匹配,則執行相應的action,如果一條命令沒有pattern而只用action,這個action將作用於待處理檔案的每一行。
這個例子中的action為‘3p‘,所以執行後的結果就是講第三行列印了出來。(如若不懂為何打出來很多條文本,請看步驟2 的介紹)
2.操作
/pattern/p:列印匹配pattern的行(這個命令會連同原檔案的內容和處理結果一同輸入到顯示器上,若使用者只想查看操作之後的結果,添加上-n選項即可。(例子如下)
很明顯可以驗證上面的原理。
sed /pattern/a+新的字串:在匹配到pattern後一行添加新的字串
sed /pattern/i+新的字串:在匹配到pattern前一行添加新的字串
sed /pattern/d:刪除匹配pattern的行(sed命令你會修改原檔案,刪除命令只表示某些行不列印輸出,而不是從源檔案中刪除)
sed /pattern/s//:s為尋找並替換命令
(1)/pattern/s/pattern1/pattern2/:尋找符合pattern的行,將該行第一個匹配pattern1 的字串替換為pattern2
(2)/pattern/s/pattern1/pattern2/g:尋找符合pattern的行,將該行所有匹配pattern1 的字串替換為pattern2
這個例子中的第一個操作就是將文本全部批量化注釋(使用位置限定符^,匹配到所有行),而第二個操作則是匹配到printf行將所有已printf開頭的注釋掉。
第一個命令是匹配到該行是a的第一個字母,使用~a~替換它,第二個命令則是替換該行所有的a.第三個命令中的&符號作用是尋找字串,作用和~a~一樣。
上面的例子則實現了在文本中插入空行,兩種解決辦法,(1)匹配行尾加以分行符號
(2)匹配行首加以分行符號
3.選項
-n:只顯示出修改後的結果
-e:允許多項編輯
-i:允許修改原檔案
使用sed工具來實現1到100的所有數的和
首先用seq工具產生1-100的序列,然後通過管道將資料傳給sed工具進行操作(實現如下)
很明顯,產生了100個序列,那麼要計算所有數的和的話就先累加所有數,使用tr命令將分行符號替換為+號
但我們又發現最後一項多了一個符號,所以在利用管道傳給計算機bc之前先將最後一項做處理,利用sed工具將最後一行的+替換為分行符號即可,最終結果就如所示。
在瞭解了sed工具的基本使用之後,現在來學習文章剛開始提到的模式空間(pattern space)。
sed工作原理是將處理的行讀入模式空間,每次執行sed命令後,將會把pattern space中的內容輸出後清空。最後一條一條的進行相同步驟處理,直到文本執行完畢。(可以對照文章開頭的圖進行理解)
一般情況下,資料的串流只會使用模式空間,但是在實現某些特殊要求的時候會用到保持空間(hold space),換句話說,如果不顯式的使用一些進階命令的話,保持空間一般都處在閑置狀態。當然,這裡可以將保持空間理解為一個倉庫,用來暫存資料。下面就介紹一些進階命令。
+g:將保持空間的內容拷貝到模式空間中,原模式空間的內容被清除
+G:將保持空間中的內容追加到模式空間的內容之後
+h:將模式空間裡的值拷貝到保持空間裡,原保持空間裡的內容被清除
+H:將模式空間裡的內容追加到保持空間 的內容之後
+d:刪除pattern中的所有行,並讀入下一行到pattern中
+x:交換保持空間和模式空間的內容
以下為實踐驗證命令的例子:
(1)在檔案aa中添加空行,這裡我們使用+G命令,即將保持空間裡的內容追加到模式空間的內容之後,在沒有進行任何操作之前,我們可以預設保持空間中就是一個空行,這樣一來,就等於是在模式空間的內容後面添加一個空行。
(2)倒著列印出aa檔案裡的所有行,一般使用的命令為tac,結果如第一部分所示,那使用sed命令怎麼來實現呢?(思路如所示)
也就是第二部分使用的命令嘍!
(3)列印匹配pattern的一行,主要思路:先逐行匹配到pattern,匹配到後將模式空間裡的內容拷貝到保持空間裡,最後匹配到行為的時候麻將先前拷貝到保持空間中的內容追加到模式空間中。
(4)實現1到100的總和,主要思路是:先將seq產生的序列通過管道傳給sed工具,接下來,利用sed行匹配的的特性將模式空間中的內容追加到保持空間中,然後交換兩個空間中的內容並用+替換分行符號(這個時候我們可以看看效果)
還能明顯1前面多了一個+,所以最後在添加命令去掉1前面的+部分(最終實現如下)。
sed 工具簡介