sed編輯器

<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->

sed 編輯器

工具sed(stream editor, 流編輯器) 是一個批處理編輯器。常被作爲管道中的過濾器。

語法:

sed 的命令行語法如下:

sed [-n] program [file-list]

sed [-n] -f program-file [file-list]

sed 工具從命令行所指定的文件或者標準輸入中獲取輸入流,除非明確指定輸出目標,否則sed 將把結果輸出到標準輸出。

 

參數:

program 命令行中的sed 程序。

program-file 表示一個包含了sed 程序的文件的完整路徑名。

file-list sed 將要處理的普通文件的完整路徑名,即sed 的輸入文件。如果沒有指定,則讀取標準輸入作爲輸入。

 

選項:

-f program-file 使得sed 從文件program-file 中讀取程序,而不是從命令行中讀取。

-i[suffix] 就地編輯文件,如果沒有這個選項,sed 將輸出送到標準輸出。該選項使得sed 將輸出送入原來的輸入文件。一旦指定了後綴名suffix sed 將備份原來的文件。

-n 指示除非使用p 指令或標誌來指定,否則不會將文本行復制到標準輸出。sed 僅僅輸出特定的行,例如那些被Print p )指令選定的行。

 

編輯器基礎

sed 程序由符合如下語法的一行或多行命令構成:

[address[,address]] instruction [argument-list]

其中address 是可選的。如果省略address ,那麼sed 將對輸入中所有行進行處理。

instruction 是一些用於改變文本的編輯指令。address 用於選定命令中的指令instruction 進行操作的文本行。argument-list 中的參數的數目和類型取決於指令instruction 。如果想把多個sed 命令放在同一行,那麼可以使用英文分號';' 來分隔這些命令。

地址

行號作爲地址可以用來選擇某一行。$ 表示輸入中的最後一行。

正則表達式作爲地址 可以用來選擇那些包含與正則表達式相匹配的字符串的行。

指令之前可以有0,1,2 個地址( 行號或正則表達式 ) :如果沒有指定地址,sed 選擇所有的行,使得該指令對輸入中所有的行進行操作;提供一個地址將使得指令作用於由該地址選擇的每一行輸入;提供兩個地址將使得指令作用於成組的輸入行。

 

指令

d 刪除指令,導致sed 不輸出被選擇的行,並且不繼續完成對該行的後續處理過程。

n 下一條指令,輸出當前選擇的行( 如果可以) ,然後重新讀入一行並從下一條命令 開始對其進行處理。

a 追加指令,在當前選擇的行之後插入一行或多行文本。如果提供了倆個地址,則在選定的每一行之後添加文本。如果沒有地址,則在每一行之後添加文本。

[address[,address]] a/

text1/

text2/

….

text

除最後一行外,所有添加的文本的每一行都必須以反斜槓結尾( 反斜槓用於指代行末的換行符) 。沒有以反斜槓結尾的行被視作要添加的文本的尾行。sed 總是輸出所添加的文本,而不論是否在命令行中使用了-n 選項,甚至在刪除被添加了文本的那一行後,被添加的文本仍會被輸出。

i 插入指令,與a 命令相同,只不過是將文本添加到選定的行之前。

c 修改指令,與a i 指令用法相同,只不過是將選定的行修改爲新的文本。

s 替換 指令 ,與vim 類似

[address[,address]] s/pattern/replacement-string/[g][p][w file]

replacement-string 可以包含符號& sed 將用與pattern 匹配的字符串替換& 符號。除非使用g 標誌,否則s 指令將只對每個選定的行中第1 個與pattern 匹配的字符串進行替換。

全局標誌g 使得sed s 指令對選定的行中匹配pattern 的非重疊字符串進行替換。

打印標誌p 使得sed 將所有應用了替換操作的行輸出到標準輸出中。

寫標誌w p 標誌類似,但它將輸出送入file 指定的文件中。

p 打印指令,將選定的行寫入標準輸出,寫入動作是立即發生的,並不反應後續指令的執行結果。

w file 寫指令,與p 指令類似,將輸出寫入由file 指定的文件中。

r file 讀指令,讀出指定文件的內容並添加到選定的行之後。

q 退出命令,使得sed 立即結束。

 

控制結構

! 使得sed 後面與其同一行的指令作用於沒有被該命令中的地址選中的每一行。3!d 刪除除第3 行以外的所有行,$!p 顯示除最後一行外的所有行。

{} 指令組,這組指令將作用於它前面的地址選定的行。

:label 標識sed 程序中的一個位置。label 作爲跳轉目標對分支指令b t 是有用的。

b [label] 無條件轉移控制到label 標識的命令。如果沒有label 則跳過當前行中剩餘的指令並從輸入中讀取下一行。

t [label] 如果最近從輸入中讀取的行使得s 指令匹配成功,則轉移到label 標識的命令。如果沒有label 則跳過剩餘的指令並從輸入中讀取下一行。

Pattern 區和Hold

sed 中有兩個緩衝區。所有的命令都是工作在Pattern 區上的。Pattern 區中保存着sed 剛剛從輸入中讀取的行。作爲臨時緩衝區,Hold 區可以在操作Pattern 區中的數據時用來暫存數據。在將數據放入Hold 區之前,它的內容爲空。

g hold 區中的內容複製到Pattern 區中。Pattern 區中的原來的內容將會丟失。

G 將一個換行符和Hold 區中的內容追加到Pattern 區的內容之後。

h pattern 區中的內容複製到Hold 區中。Hold 區中的原來的內容將會丟失。

H 將一個換行符和Pattern 區中的內容追加到Hold 區中的內容之後。

x 交換Pattern 區和Hold 區中的內容。

 

例子:

>sed 's/^.//t&/' new

>cat -n ind

1 #!/bin/sed -f

2 s/^.//t&/

>cat -n cleanup

1 #!/bin/sed -f

2 s/ *$//

> sed '/line/ p' new

> sed -n '/line/ p' new

> sed -n '3,6 p' new

> sed '5 q' new

> sed 's/^.//t&/' new

 

例子:

makefile 中自動產生依賴的一個例子。

 

>cat -n test_file.c

1 #include "headfile1.h"

2 #include "headfile2.h"

3 #include "headfile3.h"

4

5 void test_function(void)

6 {

7

8 }

>touch headfile{1,2,3}.h

>cat -n Makefile

1 %.d:%.c

2 $(CC) -M $(CFLAGS) $< > $@.$$$$;/

3 sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@;/

4 rm -f $@.$$$$

>make test_file.d

cc -M test_file.c > test_file.d.$$;/

sed 's,/(test_file/)/.o[ :]*,/1.o test_file.d : ,g' < test_file.d.$$ > test_file.d;/

rm -f test_file.d.$$

>cat test_file.d

test_file.o test_file.d : test_file.c headfile1.h headfile2.h headfile3.h


------

一點分析:

%.d: %.c

$(CC) -M $(CPPFLAGS) $< > $@.$$$$; /

sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; /

rm -f $@.$$$$

使用c 編譯器自動產生依賴(-M) ,依賴文件($<) 的依賴關係(.c 文件和其頭文件的依賴關係); 依賴關係輸出到指定臨時文件(> $@.$$$$) ,文件名爲目標(.d 目標文件).PID ,‘$$$$’PID 號,在shell 中‘$$’ 表示PID ,但是這裏需要對其轉義。

sed 依照給定的程序代碼('s,/($*/)/.o[ :]*,/1.o $@ : ,g') ,對輸入流進行處理(< $@.$$$$) ,並將處理結果輸出(> $@)

's,/($*/)/.o[ :]*,/1.o $@ : ,g'

','

sed 替換命令格式中的分隔符,典型分隔符爲'/'

s’

's'sed 替換命令

'/($*/)/.o[ :]*'

'/($*/)' 正則表達式,$* 表示make 模式規則中的徑,'/''('')' 轉義,括號在這裏的作用是將正則表達式括起來,正則表達式並不匹配轉義的括號,所以同'$*' ,就是匹配make 模式規則中的徑。

'/.o' '/''.' 的轉義,匹配'.o' 字符串。

'[ :]*' 中括號定義字符類,星號匹配0 個或多個星號前面匹配的字符。匹配0 個或多個空格,匹配0 個或多':'

所以整個表達式匹配,模式規則得到的徑後面跟'.o' 再跟0 個或多個空格,或模式規則得到的徑後面跟'.o' 再跟0 個或多個':'

'/1.o $@ : ,g'

'/1' 搜索字符串中,括號正則表達式如/(xxx/) 與不帶轉義圓括號的正則表達式匹配的字符串相同(xxx) ;在替換字符串中,轉義數字/n 代表搜索字符串的第n 個括號正則表達式/( 開始匹配的字符串。所以這裏的'/1' 就代表搜索得到的徑。

'$@' 代表,make 規則描述中的目標(.d 文件)

'g' 全局替換,針對一行中有多個匹配項。而由於sed 處理的程序沒有給出針對輸入的處理地址,只給出了處理指令(s ,替換) ,所以默認的是對所有輸入行進行查找替換。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章