1. 程式人生 > >sed 模式空間 保持空間

sed 模式空間 保持空間

sdn null 一點 初始 address 體會 問題 空間 交換

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

正常情況下,如果不顯示使用某些高級命令,保持空間不會使用到!

sed在正常情況下,將處理的行讀入模式空間,腳本中的“sed command(sed命令)”就一條接著一條進行處理,直到腳本執行完畢。然後該行被輸出,模式空間被清空;接著,在重復執行剛才的動作,文件中的新的一行被讀入,直到文件處理完畢。

技術分享圖片

一般情況下,數據的處理只使用模式空間(pattern space),按照如上的邏輯即可完成主要任務。但是某些時候,通過使用保持空間(hold space),還可以帶來意想不到的效果。

命令含義:

h,將當前模式空間中的內容覆蓋到 保持空間中,

n,用於提前讀取下一行,並且覆蓋當前模式空間中的這一行

H,將當前模式空間中的內容追加到 保持空間 中

x,交換模式空間和保持空間中的內容

g,將保持空間中的內容拷貝到模式空間中,原來模式空間裏的內容清除。

d,刪除模式空間中的所有行,並讀入下一新行到模式空間中。
D,刪除multiline pattern中的第一行,不讀入下一行。


通過幾個例子看sed的模式空間和保持空間
例子一
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‘ 對於KSH則為 sed ‘/^ *$/d‘

例子二
sed ‘/regex/{x;p;x;}‘
在匹配regex的任何行前面插入一個空行
代碼:
$ cat foo
11111111111111
22222222222222
test33333333333
44444444444444
55555555555555

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

test33333333333
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 的作用是把模式空間復制到標準輸出。
分析一下該命令執行過程中保持空間和模式空間的內容
命令 保持空間 (holdspace) 模式空間(patternspace)
x 執行前:null 執行後:test...$ 執行前:test...$ 執行後:null
p 執行前:null 執行後:test...$ 執行前:test...$ 執行後:null 輸出一個空行
x 執行前:test...$ 執行後:null 執行前:null 執行後:test...$
個人覺得上面的命令執行分析有點問題,我的分析如下:
命令 模式空間(patternspace) 保持空間 (holdspace)
x 執行前:test...$ 執行後:null 執行前:null 執行後:test...$
p 執行前:null 執行後:null但輸出一空行 執行前:test...$ 執行後:test...$
x 執行前:null 執行後:test...$ 執行前:test...$ 執行後:null
引申:能夠試驗一下 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是將模式空間的的第一行刪除);(循環刪除到模式空間裏只剩下倒數第二行時)到倒數第二行的時候,將最後一行附加到倒數第二行下面,然後最後一行不執行 D ,所以文檔的最後兩行都保存下來了。
更有 N 的另外一種用法代碼:
$ sed = foo | sed N (一定要這樣的命令格式)
1
11111111111111
2
22222222222222
3
33333333333333
4
44444444444444
5
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 執行後:11..$ 執行前:11..$ 執行後:null
第二行 G;h;d 執行前:11..$ 執行後:22..$/n11..$ 執行前:22..$ 執行後:null
第二行 G;h 執行前:22..$/n11..$執行後:33..$/n22..$/n11..$ 執行前:33..$ 執行後:33..$/n22..$/n11..$
這樣輸出以後就是文檔的反序了。

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

參考http://www.xuebuyuan.com/951950.html

http://blog.csdn.net/wanglelelihuanhuan/article/details/51591809

sed 模式空間 保持空間