?
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? 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 執行后: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?, 意思是按照文件正常順序每找到一行,就把該行放到文件的最上面一行去,這樣循環一下正好把文件的行反序顯示了。?
閱讀原文