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'來強制輸出最終結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM