sed學習筆記


sed是什么:

sed是一個非交互式的流編輯器(stream editor)。所謂非交互式,是指使用sed只能在命令行下輸入編輯命令來編輯文本,然后在屏幕上查看輸出;而所謂流編輯器,是指sed每次只從文件(或輸入)讀入一行,然后對該行進行指定的處理,並將結果輸出到屏幕(除非取消了屏幕輸出又沒有顯式地使用打印命令),接着讀入下一行。整個文件像流水一樣被逐行處理然后逐行輸出。(via Walk in Mindfields  )

sed工作機制:

sed維護兩個緩沖區,pattern space和hold space,命令開始執行之前都為空。

pattern space緩沖區用於臨時保存每次讀取的一行的內容,大部分的匹配和替換等等操作都是針對pattern space中的內容進行的,因此不會對輸入文件有任何影響,而hold space則作為后備緩沖區使用,除非指定了一些特殊的命令(例如D刪除命令),否則pattern space中的內容會在處理完一行之后清空,但hold space中的內容在處理完每一行時不會被刪除。

也就是說pattern space相當於我們的內存,hold space相當於硬盤.處理的時候在內存里,處理過的就放回硬盤.(這是我的理解,有一點點不恰當,但是因此一些概念會比較好理解.)

具體來說,可以大致分為以下幾步:

1.首先,從標准輸入流讀取一行,移除換行符,然后存入pattern space中

2.執行指定的命令,(每個命令都有一個可選的地址(可以是行號,也可能是一個正則表達式匹配),這個地址作為一個執行命令前的測試,指定了需要對那些行進行操作。當前行只有匹配的情況下才會執行命令。)

3.當指定所有的命令都執行完了之后,pattern space內容就被處理過了,sed默認會將pattern space中的內容打印到標准輸出中,移除的換行符也會打印出來。本行操作完成。

4.然后sed會讀取下一行的內容,再次執行相同的操作。直到行尾。

形式上,使用sed采用如下命令格式:

sed [options] 'SELECTION edit-instructions'  file(s) 

常用options:

-n :使用安靜(silent)模式。在一般sed的用法中,所有來自STDIN的數據一般都會被列出到終端上。但如果加上-n參數后,則只有經過sed特殊處理的那一行(或者動作)才會被列出來。

-e :直接在命令列模式上進行sed的動作編輯;

-f :直接將sed的動作寫在一個文件內,-f filename 則可以運行filename內的sed動作;

-r :sed 的動作支持的是延伸型正規表示法的語法。(默認是基礎正規表示法語法)

-i :直接修改讀取的文件內容,而不是輸出到終端。

 

1)范圍選取

SELECTION 可以如下表達:

  • 單個行號:如1為取第一行,5為取第五行,$為取最后一行             
  • 行范圍:如5,$ 為取從第五行到最后一行之間的文本行
  • 單個正則匹配:如/string/ 為取包含string的行
  • 一個正則匹配范圍:如/^on/,/off$/ 為取從on開頭的行到off結尾的行之間(含這兩個匹配行)所包含的文本行。
  • 行范圍與正則匹配范圍集合:如10,/man/表示從第10行到包含有man的行之間的文本
  • 除去所匹配行外的范圍:如/Llew/! 表示除了匹配Llew的行外其余的文本行     

2)打印命令

基本語法:SELSECTIONp 打印pattern space中的內容 

Task1:打印包含Franklin的行

sed -n '/Franklin/p' phonelist 

注意,選項-n 表示所有都不打印,而僅僅打印出匹配的行,可以試一試沒有這個選項的情況。回顧sed機制,它會將文本一行行放在pattern space,不管你做什么樣的后續操作、甚至不做任何編輯動作,它都會在command執行完后把pattern space打出來,這你就理解了為什么要用這個選項。

3)處理命令

a)  增改操作:

基本語法:

SELECTIONx\ 
text

其中斜杠后有回車,而x則為:

i 表示插入選中行前

a 表示追加在選中行之后

c 表示將選中行修改為text

Task2:在第二行前插入一個聯系人Jonney, Wang 923-3322 

sed '2i\ 

Jonney, Wang 923-3322' phonelist  

Task3:在Martin, Marty所在行之后加入聯系人Jonney, Wang 923-3322

sed '/Martin, Marty/a\  

Jonney, Wang 923-3322' phonelist 

Task4:將名字為Llewellyn的行記錄都記為“BANNED”

sed '/Llewellyn/c\

BANNED' phonelist 

b)刪除操作

基本語法:

SELECTIONd ,清除pattern space中的所有內容

Task5 刪除最后一行:

sed '$d' phonelist

c)替換操作:

基本語法:

'SELECTION s/old string/new string/’ 替換所選區域中第一次出現的old string

'SELECTION s/old string/new string/g’ 替換所選區域中所有的old string

'SELECTION y/string1/string2/’ 對所選區域中的string1所含字符對應替換為string2中同位置的字符,與tr命令相同。

Task6:將第一個Robin替換為Robbins

sed 's/Robin/Robbins/' phonelist 

Task7:將所有Rob替換為John 

sed 's/Rob/John/g' phonelist

Task8:將/usr/bin/中的/bin/替換為/bin 

sed 's/\/bin\//\/bin/' paths 

在這種出現很多/的文件時需要\來進行轉義,稍微一多就容易出錯,那么采用如下的方式把替換分隔符的方式進行就好,其中感嘆號只是一個其他類字符,換做另外一個字符(例如@)也是沒有關系的: 

sed 's!/bin/!/bin!' paths 

Task9:加密所有的1234,規則為將文件中1、2、3、4對應改為A、B、C、D: 

sed 'y/1234/ABCD/' phonelist

d)寫文件操作:

基本語法:'SELECTION command/w filename’

Task9:將所有Rob 改為Robbin,並將結果寫到一個叫做result 的文件中

sed 's/Rob/Robbin/gw result' phonelist

e)讀文件操作:

基本語法:'SELECTION command/r filename’

Task10:如果phonelist中存在Patterson,則將文件paths的內容加入到Patterson后的那一行

sed '/Patterson/r paths' phonelist 

f)批處理操作:

如果要處理的很多,我們也可以將sed命令寫入一個腳本,然后運行時采用-f選項指定運行該腳本就行。請注意sed會將第一條命令執行的結果發給第二條執行,因此命令的順序尤為重要。

基本語法:sed -f scriptfile  filename

另一種方式是使用-e選項,基本語法為:

-e ‘command1’ –e ‘command2’

Task11:將Martin替換Mary,將Tearrey替換為Tearrey 

sed -e 's/Martin/Mary/' -e 's/Terrell/Tearrey/' phonelist

另外一種方法,有點類似於C語言中分號的使用: 

sed 's/Martin/Mary/;s/Terrell/Tearrey/' phonelist

 


免責聲明!

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



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