通過幾個例子看sed的模式空間與保持空間


 

SED之所以能以行為單位的編輯或修改文本,其原因在於它使用了兩個空間:一個是活動的“模式空間(pattern space)”,另一個是起輔助作用的“暫存緩沖區(holdingspace)這2個空間的使用。

 

sed編輯器逐行處理文件,並將輸出結果打印到屏幕上。sed命令將當前處理的行讀入模式空間(pattern space)進行處理,sed在該行上執行完所有命令后就將處理好的行打印到屏幕上(除非之前的命令刪除了該行),sed處理完一行就將其從模式空間中刪除,然后將下一行讀入模式空間,進行處理、顯示。處理完文件的最后一行,sed便結束運行。sed在臨時緩沖區(模式空間)對文件進行處理,所以不會修改原文件,除非顯示指明-i選項。

 

sed之所以能以行為單位的編輯或修改文本,其原因在於它使用了兩個空間:一個是活動的“模式空間(pattern space)”,另一個是起輔助作用的“保持空間(hold space)這2個空間的使用。

 

模式空間:可以想成工程里面的流水線,數據之間在它上面進行處理,用於處理文本行。

 

保持空間:可以想象成倉庫,我們在進行數據處理的時候,作為數據的暫存區域,用於保留文本行,是保存已經處理過的輸入行,默認有一個空行。 

 

與模式空間和暫存空間(hold space)相關的命令:

 

n 輸出模式空間行,讀取下一行替換當前模式空間的行,執行下一條處理命令而非第一條命令。

 

N 讀入下一行,追加到模式空間行后面,此時模式空間有兩行。

 

h 把模式空間的內容復制到保留空間,覆蓋模式

 

H 把模式空間的內容追加到保留空間,追加模式

 

g 把保留空間的內容復制到模式空間,覆蓋模式

 

G 把保留空間的內容追加到模式空間,追加模式

 

x 將暫存空間的內容於模式空間里的當前行互換。

 

! 對所選行以外的所有行應用命令。

 

 

 

注意:暫存空間里默認存儲一個空行。

 

 

例子一 
sed G 
在文件每一行下面輸出一個空行 

代碼:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed G foo 
11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 


解釋: 

sed 中 G 的用法 
The G function appends the contents of the holding area to the contents of the pattern space. The former and new contents are separated by a newline. The maximum number of addresses is two. 

hold space : 保持空間(或者叫保留空間、緩沖區),初始為空 
pattern space :模式空間 

在上面的例子中,將為空的hold space附加到文件的每一行后面,所以結果是每一行后面多了一個空行 

引申出: 
sed '/^$/d;G' 
在文件的每一個非空行下面輸出一個空行 
sed '/^$/d;G;G' 
在文件的每一個非空行下面輸出兩個空行 

代碼:

$ cat foo 
11111111111111 
22222222222222 

33333333333333 
44444444444444 
55555555555555 

$ sed '/^$/d;G' foo 
11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 



注:有時會有一些由空格符或者TAB組成的空行,前面的正則式 ^$ 就不能匹配到這樣的行,則可以這樣 
sed '/[[:space:]]/d;G' 


例子二 
sed '/regex/{x;p;x;}' 
在匹配regex的所有行前面插入一個空行 
代碼:

$ cat foo 
11111111111111 
22222222222222 
test33333333333333 
44444444444444 
55555555555555 

$ sed '/test/{x;p;x;}' foo 
11111111111111 
22222222222222 

test33333333333333 
44444444444444 
55555555555555 


解釋: 
sed 中 x 的用法 
The exchange function interchanges the contents of the pattern space and the holding area. The maximum number of addresses is two. 
即交換保持空間hold space和模式空間pattern space的內容 

sed 中 p 的作用是把模式空間復制到標准輸出。 

分析一下該命令執行過程中保持空間和模式空間的內容 

命令 保持空間 模式空間 
x 執行前:null 執行后:test\n 執行前:test\n 執行后:null 
p 執行前:null 執行后:test\n 執行前:test\n 執行后:null 輸出一個空行 
x 執行前:test\n 執行后:null 執行前:null 執行后:test\n 

(注:把test所在的行簡寫為test了) 

引申: 
可以試驗一下 sed '/test/{x;p;}' foo 或者 sed '/test/{p;x;}' foo 等,看看結果,體會兩個空間的變化 

相應的: 
sed '/regex/G' 是在匹配regex的所有行下面輸出一個空行 
sed '/regex/{x;p;x;G;}' 是在匹配regex的所有行前面和下面都輸出一個空行 


例子三 
sed 'n;G;' 
在文件的偶數行下面插入一個空行 
代碼:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed 'n;G;' foo 
11111111111111 
22222222222222 

33333333333333 
44444444444444 

55555555555555 

解釋: 
sed 中 n 的用法:將模式空間拷貝於標准輸出。用輸入的下一行替換模式空間。 

執行 n 以后將第一行輸出到標准輸出以后,然后第二行進入模式空間,根據前面對 G 的解釋,會在第二行后面插入一個空行,然后輸出;再執行 n 將第三行輸出到標准輸出,然后第四行進入模式空間,並插入空行,依此類推 

相應的: 
sed 'n;n;G' 表示在文件的第 3,6,9,12,... 行后面插入一個空行 
sed 'n;n;n;G' 表示在文件的第 4,8,12,16,... 行后面插入一個空行 
sed 'n;d' 表示刪除文件的偶數行 


例子四 
sed '$!N;$!D' 
輸出文件最后2行,相當於 tail -2 foo 

代碼:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 
44444444444444 
55555555555555 

$ sed '$!N;$!D' foo 
44444444444444 
55555555555555 



解釋: 

D 刪除模式空間內第一個 newline 字母 \n 前的資料。 
N 把輸入的下一行添加到模式空間中。 

sed '$!N;$!D' : 對文件倒數第二行以前的行來說,N 將當前行的下一行放到模式空間中以后,D 就將模式空間的內容刪除了;到倒數第二行的時候,將最后一行附加到倒數第二行下面,然后最后一行不執行 D ,所以文件的最后兩行都保存下來了。 


還有 N 的另外一種用法 
代碼:

$ sed = foo | sed N 

11111111111111 

22222222222222 

33333333333333 

44444444444444 

55555555555555 

$ sed = foo | sed 'N;s/\n/   /' 
1       11111111111111 
2       22222222222222 
3       33333333333333 
4       44444444444444 
5       55555555555555 

解釋: 
N 的作用是加上行號,可以用於格式化輸出文件 


例子五 
sed '1!G;h;$!d' 
sed -n '1!G;h;$p' 
將文件的行反序顯示,相當於 tac 命令(有些平台沒有這個命令) 

代碼:

$ cat foo 
11111111111111 
22222222222222 
33333333333333 

$ sed '1!G;h;$!d' foo 
33333333333333 
22222222222222 
11111111111111 

$ sed -n '1!G;h;$p' foo 
33333333333333 
22222222222222 
11111111111111 


解釋: 
sed 中 h 用法:h 
The h (hold) function copies the contents of the pattern space into a holding area, destroying any previous contents of the holding area. 
意思是將模式空間的內容保存到保持空間中去 

sed 中的 d 表示刪除模式空間。 

1!G表示除了第一行以外,其余行都執行G命令;$!d表示除了最后一行以外,其余行都執行d命令。 

看一下sed '1!G;h;$!d'命令執行過程中保持空間與模式空間的變化: 

命令 保持空間 模式空間 
第一行 h;d 執行前:null 執行后:1111\n 執行前:1111\n 執行后:null 
第二行 G;h;d 執行前:1111 執行后:2222\n1111\n 執行前:2222\n 執行后:null 
第二行 G;h 執行前:2222\1111\n 執行后:3333\n2222\n\1111\n 執行前:3333\n 執行后:3333\n2222\n\1111\n 

(注:把各個行簡寫了) 

這樣輸出以后就是文件的反序了。 

題外話:在vi中對一個文件進行反序顯示的命令是 :g/./m0 , 意思是按照文件正常順序每找到一行,就把該行放到文件的最上面一行去,這樣循環一下正好把文件的行反序顯示了。 

閱讀原文


免責聲明!

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



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