sed中關於pattern space和hold space的小實例一則(tac)

sed中關於pattern space和hold space的小實例一則

今天在看園子裏的sed文章,瞭解到pattern space和hold space. 但是看到逆序輸出文件內容的例子時有些卡殼了。雖然瞭解之後覺得很簡單,但是對我等菜鳥來說還是需要揣摩揣摩的。說到底還是不能用Unix的方式來思考和看待問題,還需努力。

sed的用法是: sed OPTIONS... [SCRIPT] [FILE...]

簡單說下sed的工作流程。pattern space和hold space默認都是空的。sed讀入一行內容,刪除尾部的換行符,存入pattern space, 然後執行SCRIPT,如果OPTIONS裏沒有 -n, pattern space裏的內容會被輸出到stdout(若讀入時含有換行,這裏會輸出換行), 如果有-n, 則不輸出,接下來就讀取下一行數據,重複上述步驟。

再說一下一會要在SCRIPT中用到的幾個命令。
d : 清空pattern space中的內容,立即開始下個循環(意思是跳過默認的輸出pattern space內容的階段???不知理解的對不對)
h : 用pattern space中的內容替換hold pattern中的內容
H : 在hold space中的內容後面追加一個換行,把pattern space中的內容追加到hold space中
g : 用hold space中的內容替換pattern space中的內容
G : 在pattern space中的內容後面追加一個換行,把hold space中的內容追加到pattern space中

h, g會替換(可以理解爲先清空,再複製), H, G是追加。


這個例子是這樣的,有一個文件myfile.txt, 內容如下:

This is the 1st line.
2nd line is here.
i'm the 3rd.
why i am the last one?

 

期望逆序輸出其內容,也就是如下效果

why i am the last one?
i'm the 3rd.
2nd line is here.
This is the 1st line.

 

解法如下:

$ sed '1!G;h;$!d' myfile.txt

 

執行步驟:
首先讀取myfile.txt的第一行到pattern space,如下所示:

    pattern space                    hold space
     ------------                    ------------
    This is the 1st line.            <null>

 

執行命令'1!G;h;$!d', 由於是第一行,所以'1!G'被跳過,執行'h', 用pattern space中的內容替換hold space中的內容,由於不是最後一行,執行'$!d'清空pattern space,此時狀態是:

     pattern space                    hold space
     ------------                    ------------
    <null>                            This is the 1st line.

 

讀取第二行到pattern space

     pattern space                    hold space
     ------------                    ------------
    2nd line is here.                This is the 1st line.

 

已經不是第一行了,所以執行'1!G', hold space中的內容追加都pattern space

     pattern space                    hold space
     ------------                    ------------
    2nd line is here.                This is the 1st line.
    This is the 1st line.

 

執行'h', pattern space的內容替換hold space

     pattern space                    hold space
     ------------                    ------------
    2nd line is here.                2nd line is here.
    This is the 1st line.            This is the 1st line.

 

執行'$!d', 清空pattern space, 讀取第三行到pattern space

     pattern space                    hold space
     ------------                  ------------

    i’m the 3rd.                    2nd line is here. 
                                    This is the 1st line.

 

執行'1!G', hold space中的內容追加都pattern space

     pattern space                    hold space
     ------------                  ------------

    i’m the 3rd.                     2nd line is here. 
    2nd line is here.                 This is the 1st line.
    This is the 1st line.

 

執行'h', pattern space的內容替換hold space

     pattern space                    hold space
     ------------                  ------------

    i’m the 3rd.                     i’m the 3rd. 
    2nd line is here.                 2nd line is here. 
    This is the 1st line.            This is the 1st line.

 

執行'$!d', 清空pattern space, 讀取第四行到pattern space

     pattern space                    hold space
     ------------                  ------------

    why i am the last one?            i’m the 3rd. 
                                    2nd line is here. 
                                    This is the 1st line.

 

執行'1!G', hold space中的內容追加都pattern space

複製代碼
     pattern space                    hold space
     ------------                  ------------

    why i am the last one? 
    i’m the 3rd.                     i’m the 3rd. 
    2nd line is here.                 2nd line is here. 
    This is the 1st line.            This is the 1st line.
複製代碼

 

執行'h', pattern space的內容替換hold space

複製代碼
     pattern space                    hold space
     ------------                  ------------

    why i am the last one?             why i am the last one? 
    i’m the 3rd.                     i’m the 3rd. 
    2nd line is here.                 2nd line is here. 
    This is the 1st line.            This is the 1st line.
複製代碼

 

現在已經是最後一行,'$!d'將不會被執行,所有SCRIPT執行完之後,輸出pattern space中的內容

why i am the last one?
i'm the 3rd.
2nd line is here.
This is the 1st line.

 

得到最終結果。

根據info sed,默認情況下,pattern space中的內容會在兩次循環之間(輸出之後,讀取之前)被清空; 而hold space則不會自動清空。

----------------------------------
這個命令還有一種寫法

$ sed -n '1!G;h;$p' myfile.txt

 

這裏用了-n選項,如前面所說,它會跳過SCRIPT執行完後,pattern space的輸出動作,而'$p'則是的執行到最後一行的時候,執行'p'來強制輸出最終結果。

發佈了48 篇原創文章 · 獲贊 8 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章