例說sed正則表達式
sed:stream editorvim
流線型,非交互式的編輯器。它每次只處理一行文件並把輸出打印到屏幕上。緩存
Pattern space: 模式空間即存放當前正在處理的行的緩存空間。 一旦處理工做完成,sed就會把結果輸出到屏幕,而後清空模式空間並把下一行讀入模式空間,進行相關處理;直到最後一行。sass
sed是無破壞性的,它不更改原文件,除非你使用重定向保存輸出結果。bash
對於一行文本,sed命令是依次執行的,若是有多個命令的話。這時,要注意各命令之間可能產生的相互影響。編輯器
對於多個sed命令,咱們能夠用「{}」把它們括起來。但要注意,右花括號必定要單獨成行。測試
sed命令後不能有空格,前面則無所謂。this
咱們能夠把一系列的sed命令寫入文件中並用sed 的-f選項調用spa
好啦,打住先(沒提到的後面都會有例子說明的,嘿嘿).net
首先,咱們來看看sed的語法及尋址方式:
語法:
sed [options] 'command' filename(s)
尋址方式:
1.單行尋址:[line-address]command;尋找匹配line-address的行並進行處理。
2.行集合尋址:[regexp]command ;匹配文件中的一行或多行,如/^A/command匹配全部以A開頭的行。
3.多行尋址: [line-address1,line-address2] command;尋找在兩個地址之間的內容並作相應的處理。
4.嵌套尋址:10,20{
/^$/d
#上面三種尋址方法均可以應用在這裏
}
接下來,瞧瞧sed的一些命令和選項
sed選項:
選項 |
功能 |
-e |
容許屢次編輯 |
-f |
跟隨腳本文件名 |
-n |
禁止默認輸出 |
sed的相關命令:
命令 |
功能 |
a\ |
向當前行添加文本行 |
c\ |
用新的文本行取代當前行裏的文本 |
i\ |
在當前行以前插入文本 |
d |
刪除行 |
h |
把模式空間內容複製到一個固定緩存 |
H |
把模式空間內容添加到一個固定緩存 |
g |
把固定緩存裏的全部文本都複製到模式緩存,重寫模式緩存的內容 |
G |
把固定緩存裏的全部文本添加到模式緩存 |
l |
列出不打印的字符 |
p |
打印行 |
P(大寫) |
多行打印,輸出多行模式空間裏的第一部分,直到第一個嵌入的換行符爲止 |
n |
輸出模式空間的內容並讀取下一行 |
N |
讀取新的輸入行並將其添加到模式空間的現有內容以後來建立多行模式空間 |
q |
結束或退出 |
r |
讀入行,從某個文件 |
! |
把命令應用到選定行以外的其它全部行 |
s |
替換 |
替換標誌:
標誌 |
功能 |
g |
全局替換 |
p |
打印 |
w |
把行寫到文件中 |
x |
交換;用模式空間的內容交換固定緩存的內容 |
y |
轉換,如大小寫轉換 |
sed支持的一些元字符:
元字符 |
功能 |
例 |
^ |
定位行開頭 |
/^sed/:匹配全部以sed開頭的行 |
$ |
定位行結尾 |
/sed$/:匹配全部以sed結尾的行 |
. |
匹配單個字符,不包括換行符 |
/s.d/:匹配包含一個s,後跟一個字符,再跟一個e的行 |
* |
匹配零個或多個字符 |
/*sed/:匹配的行有零個或多個空格且其後跟模式sed |
[] |
匹配集中的一個字符 |
/[Ss]ed/:匹配包含sed或Sed的行 |
[^] |
反上 |
/[^Ss]ed/:匹配的行不包含s,S且後跟ed |
\(..\) |
保存被匹配的字符 |
s/\(love\)/\1 ly/:用lovely取代love。把被標誌的部分標爲1,之後就能用\1引用。最多容許使用9個標記,第一個從模式的最左端開始。如上面的love就保存在寄存器1裏且被記在替換串裏。 |
& |
保存搜索串以便記在替換串裏 |
s/sed/fuck&/:&表明搜索串sed。此例中sed將被fucksed替換 |
\< |
定位詞開頭 |
/\<sed/:匹配以sed開頭的一個詞 |
\> |
定位詞結尾 |
/sed\>/:匹配以sed結尾的一個詞 |
x\{m\} |
字符x重複m次 |
o\{3\}:匹配的行裏o要連續出現3次 |
x\{m,\} |
字符x至少重複m次 |
o\{3\,}:匹配的行裏o至少要連續出現3次 |
x\{m,n\} |
字符x至少重複m次且不超過n次 |
O\{3,5\}:匹配的行裏要o至少要連續出現3次但不超過5次 |
好啦,下面就有例子來講話喔,呵呵
datafile的內容:
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
e.g. 1:
a\--找到以north開頭的行並在其後添加不少FUCK
[fedora@novice chap04]$ sed '/^north/a\FUCK FUCK FUCK FUCK \nkcuf kcuf kcuf kcuf' datafile
northwest NW Charles Main 3.0 .98 3 34
FUCK FUCK FUCK FUCK
kcuf kcuf kcuf kcuf
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
FUCK FUCK FUCK FUCK
kcuf kcuf kcuf kcuf
north NO Margot Weber 4.5 .89 5 9
FUCK FUCK FUCK FUCK
kcuf kcuf kcuf kcuf
central CT Ann Stephens 5.7 .94 5 13
***************************************************************************************************
發如今bash中只能像上面那樣輸入且a後的\無關緊要 ; 並不像書上說的那樣,不知是否是跟SHELL有關係
通常,a後是要帶\的,有時還要帶兩個。若是要添加的文本不止一行的話,除了最後一行每一行的結尾都要跟\。以上只是在控制檯輸入,在腳本中輸入的狀況仍是和書上說的同樣的。
***************************************************************************************************
e.g. 2:
i\ --在以central開頭的行前分行插入FUCK
[fedora@novice chap04]$ sed '/central/i\F\nU\nC\nK' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
F
U
C
K
central CT Ann Stephens 5.7 .94 5 13
***************************************************************************************************
通常,若是要添加的文本不止一行的話,除了最後一行每一行的結尾都要跟\。但在我這裏好像有點不同,在終端直接輸入時。
****************************************************************************************************
e.g. 3:
c\--把有sourth的行所有用FUCK取代
[fedora@novice chap04]$ sed '/south/c\FUCK' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
FUCK
FUCK
FUCK
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
****************************************************************************************************
*其它與e.g.1 ,e.g. 2 相似
****************************************************************************************************
e.g. 4:
d--刪除第一行
[fedora@novice chap04]$ sed '1d' datafile
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
d--刪除1-4行
[fedora@novice chap04]$ sed '1,4d' datafile
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
d--刪除有north的行
[fedora@novice chap04]$ sed '/north/d' datafile
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
central CT Ann Stephens 5.7 .94 5 13
***************************************************************************************************
e.g. 5:
s--替換。用FUCK替換north.
[fedora@novice chap04]$ sed 's/north/FUCK/' datafile
FUCKwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
FUCKeast NE AM Main Jr. 5.1 .94 3 13
FUCK NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
s--替換。用FUCK替換全部以south開頭的行中的south.
[fedora@novice chap04]$ sed '/^south/s/south/FUCK/g' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
FUCKwest SW Lewis Dalsass 2.7 .8 2 18
FUCKern SO Suan Chin 5.1 .95 4 15
FUCKeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
s--替換。 尋找大於1少於10的一位小數並用FUCK+&替代。這裏的&保存了前面的小數
[fedora@novice chap04]$ sed 's/[0-9]\.[0-9]/FUCK&/' datafile
northwest NW Charles Main FUCK3.0 .98 3 34
western WE Sharon Gray FUCK5.3 .97 5 23
southwest SW Lewis Dalsass FUCK2.7 .8 2 18
southern SO Suan Chin FUCK5.1 .95 4 15
southeast SE Patricia Hemenway FUCK4.0 .7 4 17
eastern EA TB Savage FUCK4.4 .84 5 20
northeast NE AM Main Jr. FUCK5.1 .94 3 13
north NO Margot Weber FUCK4.5 .89 5 9
central CT Ann Stephens FUCK5.7 .94 5 13
****************************************************************************************************
剛開始時用的是下面的語句:
sed '[0-9][0-9]$/FUCK&/' datafile,怎麼弄都不成功。
不知是怎麼回事。
*****************************************************************************************************
e.g. 6:
p--打印:默認打印全部的行。這裏用-n選項過濾無關的行
[fedora@novice chap04]$ sed -n '/north/p' datafile
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
發現一個問題:p也會把匹配的行打印兩次:
[fedora@novice chap04]$ sed '/north/p' datafile
northwest NW Charles Main 3.0 .98 3 34
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94
也就是說不使用-n選項的話,p會打印出匹配兩次
P--多行打印:在執行完全部命令後模式空間的內容會自動輸出,在下面的例子中能夠看到匹配的行輸出了兩次,可是-n選項會抑制這個動做。只有在與D,N配合使用時纔會輸出模式空間裏的第一行,此時不用-n選項。
[fedora@novice chap04]$ sed '/north/P' datafile
northwest NW Charles Main 3.0 .98 3 34
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
****************************************************************************************************
e.g. 7:
D--多行刪除:選項看到d與D的不一樣之處了麼?其中空行分別爲1,2,3,4行。
[fedora@novice chap04]$ cat >test
this is a test line
this is a test line
this is a test line
this is a test line
this ia a test line
[fedora@novice chap04]$ sed -e '/^$/N' -e '/^\n$/d' test
this is a test line
this is a test line
this is a test line
this is a test line
this ia a test line
[fedora@novice chap04]$ sed -e '/^$/N' -e '/^\n$/D' test
this is a test line
this is a test line
this is a test line
this is a test line
this ia a test line
****************************************************************************************************
能夠看到,與N配合的狀況下:
使用d,如有偶數個空行將會全被刪除,如有奇數個空行將會保留一行。這是由於d刪除的是整個模式空間的內容。一旦遇到第一個空行就立刻讀入下一行,而後兩行都刪除。若是第三行爲空且下一行不爲空則命令不執行,空行被輸出。
使用D,當遇到兩個空行時D會刪除兩個空行中的第一個,而後再讀入下一行,若是是空行則刪除第一行,若是空行後有文本則模式空間能夠正常輸出。
***************************************************************************************************
e.g. 8:關於N命令與-e選項在上面已在應用,這裏就不舉例啦,偷點懶哈,嘿嘿。
*****************************************************************************************************
e.g. 9:
r--從文件中讀取:從test中讀取相關的內容添加到datafile中全部匹配的行的後面。
[fedora@novice chap04]$ sed '/^south/r test' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
**********************************
FUCK FUCK FUCK FUCK ,FUCK TOO MUCH
**********************************
southern SO Suan Chin 5.1 .95 4 15
**********************************
FUCK FUCK FUCK FUCK ,FUCK TOO MUCH
**********************************
southeast SE Patricia Hemenway 4.0 .7 4 17
**********************************
FUCK FUCK FUCK FUCK ,FUCK TOO MUCH
**********************************
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
***************************************************************************************************
e.g. 10
w--寫入文件:把datafile中全部匹配的行寫入到test文件中
[fedora@novice chap04]$ sed '/^south/w test' datafile|cat test
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
***************************************************************************************************
e.g. 11
n--next:若是有能匹配western行,則n命令使得sed讀取下一行,而後執行相應命令
[fedora@novice chap04]$ sed -e '/western/n' -e 's/SW/FUCK/' datafile|head -n 4
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest FUCK Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
***************************************************************************************************8
e.g. 12
y--變換:
[fedora@novice chap04]$ sed '3,5y/s/S/' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
SouthweSt SW LewiS DalSaSS 2.7 .8 2 18
Southern SO Suan Chin 5.1 .95 4 15
SoutheaSt SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
[fedora@novice chap04]$ sed '1y/3/9/' datafile
northwest NW Charles Main 9.0 .98 9 94
western WE Sharon Gray 5.3 .97 5 23
***************************************************************************************************
替換的類型要一致,數字與字母之間不能相互替換。
且對正則表達式的元字符不起做用。
*****************************************************************************************************
e.g. 13:
q--退出:
打印三行後退出
[fedora@novice chap04]$ sed '3q' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
用相應的字符作出替換後退出
[fedora@novice chap04]$ sed -e 'y/northwest/ABCDEFGHI/' -e q datafile
ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34
這樣也能夠的
[fedora@novice chap04]$ sed '{ y/northwest/ABCDEFGHI/; q;}' datafile
ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34
多個命令寫在一行時能夠用-e選項,也能夠用花括號把全部命令括起來並用分號隔開且最後一個分號無關緊要,在個人實驗環境下。
**************************************************************************************************
e.g. 14:
H/h/G/g--保存和取得
下面是這幾個命令的一些組合,能看出些什麼來麼?
[fedora@novice chap04]$ sed -e '/northeast/h' -e '$g' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
northeast NE AM Main Jr. 5.1 .94 3 13
[fedora@novice chap04]$ sed -e '/northeast/h' -e '$G' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
northeast NE AM Main Jr. 5.1 .94 3 13
[fedora@novice chap04]$ sed -e '/northeast/H' -e '$g' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
northeast NE AM Main Jr. 5.1 .94 3 13
[fedora@novice chap04]$ sed -e '/northeast/H' -e '$G' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
northeast NE AM Main Jr. 5.1 .94 3 13
由於呢,H/G在相應空間的內容以後放置一個換行符,且後面緊跟模式空間的內容;而g/h的呢都是取代相應空間的內容,因此就有上面的不一樣結果喔
***************************************************************************************************
e.g. 15
x--交換模式/保持空間內容
首先匹配第一個包含north的行放入保持緩存,而後匹配第一個包含south的行放入模式空間,最後把二者的內容交換。
[fedora@novice chap04]$ sed -e '/north/h' -e '/south/x' datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
****************************************************************************************************
e.g. 16
sed腳本:
[fedora@novice chap04]$ vim sedlist
/central/a\
------This is a test--------
/northeast/i\
------This is a test too------
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
------This is a test too------
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
------This is a test--------
能夠在裏面添加註釋,以#開頭的行被認爲是註釋
若有多行,則每行都要以\結尾,除了最後一行。如,下面的腳本是能夠正常執行的。
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands list
/central/a\
------This is a test too--------\
------Hi am here----------------\
#now ,the second test
/northeast/i\
------This is a test ------
***************************************************************************************************
****************************************************************************************************
*******************************************************************************************************
高級流控制命令
b 分支 :無條件轉移
t 測試 :有條件的轉移
它們將腳本中的控制轉移到包含特殊標籤的行;若是沒有標籤則直接轉移到腳本的末尾。只有當替換命令改變當前行時纔會被執行。
標籤:任意的字符組合且長度不大於7,它自己佔據一行且以冒號開頭
:mylabel
冒號和標籤之間不能有空格,標籤後的空格會被當作標籤的一部分。
標籤和命令之間容許有空格。
b 分支:[address] b [label]
b --> branch,在腳本中將控制權轉到另外一行,經過它你能夠跳到你想去的地方,是否是有點像c中的goto呀?
它能夠將一組命令當作一個過程來執行且這個過程在腳本中能夠重複執行,只要條件知足。
e.g 17
b--分支
看下面的例子:
e.g. 17.1
匹配以north加空格開頭的行,若匹配則轉到:label後面的命令,在以s開頭的行前插入FFFFFFFFFFFFFFUCK ;
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
:label
/^s/i\
FFFFFFFFFFFFFFUCK
/^north / b label
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
FFFFFFFFFFFFFFUCK
southwest SW Lewis Dalsass 2.7 .8 2 18
FFFFFFFFFFFFFFUCK
southern SO Suan Chin 5.1 .95 4 15
FFFFFFFFFFFFFFUCK
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
其實這也是個循環,反覆執行兩個標籤間的命令,直到模式不匹配。可是,如上,無論匹配與否兩個標籤間的內容至少會被執行一次。也就是說,正常狀況下上面的命令都會被執行一次。看下面的例子:
e.g 17.2
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
:label
/^n/d
/^A/b label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
看到了吧!雖然模式不匹配,但仍是執行了兩個標籤間的內容,嘿嘿!再看看上面,和do-while語句有什麼異同?
e.g. 17.3
若是匹配,什麼都不作,不然執行後的命令向以cent開頭的行後添加一些內容
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
:label
/^A/b label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
e.g. 17.4
另外一種循環模式
command1
/pattern/b label
command2
label:
command3
首先執行command1,而後看模式是否匹配,若匹配則執行command3,不然執行command2,command3
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
/^n/d
/^A/b label
s/south/SSSSSS/
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
western WE Sharon Gray 5.3 .97 5 23
SSSSSSwest SW Lewis Dalsass 2.7 .8 2 18
SSSSSSern SO Suan Chin 5.1 .95 4 15
SSSSSSeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
模式不匹配,順序執行各命令,下面來看匹配的狀況:
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
/^w/d
#north後有一個空格
/^north /b label
s/south/SSSSSS/
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
SSSSSSwest SW Lewis Dalsass 2.7 .8 2 18
SSSSSSern SO Suan Chin 5.1 .95 4 15
SSSSSSeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
很顯然,這裏並無跳過第二個命令,可是理論上只模式空間匹配的話就會直接轉到:label後的命令的呀!這究竟是爲何呢?咱們來看下一個腳本,只對上個腳本作一點點修改:
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
/^w/d
#north後有一個空格
/^north /b label
s/north /SSSSSS/
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
此次結果正常啦,它找到了以north加空格開頭的行,並跳過了第二個命令。
再來看兩個例子:
在第二個命令後再添加一個命令s/south/NNNNNN看會有怎樣的結果:
[fedora@novice chap04]$ cat sedlist
#This script is a test for sed commands
/^w/d
/^north /b label
s/north /SSSSSS/
s/south/NNNNNN/
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW Charles Main 3.0 .98 3 34
NNNNNNwest SW Lewis Dalsass 2.7 .8 2 18
NNNNNNern SO Suan Chin 5.1 .95 4 15
NNNNNNeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
顯然,s/north /SSSSSS/ 沒有被執行而s/south/NNNNNN/ 被執行啦
又一個例子:
[fedora@novice chap04]$ cat sedlist1
#This script is a test for sed commands
/^w/d
/^north/b label
p
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist1 datafile
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
能夠看到p應用到了除以north開頭的全部行!再來一個例子:
[fedora@novice chap04]$ cat sedlist1
#This script is a test for sed commands
/^w/d
/^north/b label
p
l
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist1 datafile
northwest NW Charles Main 3.0 .98 3 34
southwest SW Lewis Dalsass 2.7 .8 2 18
southwest\tSW\tLewis Dalsass\t\t2.7\t.8\t2\t18\r$
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southern\tSO\tSuan Chin\t\t5.1\t.95\t4\t15\r$
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
southeast \tSE\tPatricia Hemenway\t4.0\t.7\t4\t17\r$
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
eastern\t\tEA\tTB Savage\t\t4.4\t.84\t5\t20\r$
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
central\t\tCT \tAnn Stephens\t\t5.7\t.94\t5\t13\r$
central CT Ann Stephens 5.7 .94 5 13
--FUCK!!!
Just a test!
Take it easy!!!
看到了麼?P,l都只應用到了除以north開頭的全部行上!!!
從上面的一堆例子中,能夠獲得:在
command1
/pattern/b label
command2
label:
command3
模式中 只有 針對 匹配pattern的行 的操做纔會被跳過!
e.g. 17.5
如何指定執行上例中的command2或command3中的一個
commmand1
/pattern/b label
command2
b
:label
command3
首先執行command1,而後執行/pattern/b label,若是模式匹配則直接跳到command3並執行相關命令,不然跳到command2在執行完相關命令後遇到分支b,分支b將控制轉到腳本的結尾,繞過了command3.
下面看一個簡單的例子:
[fedora@novice chap04]$ cat sedlist1
#This script is a test for sed commands
/^e/d
/^DDD/b label
s/west/SSSSSS/
b
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!
[fedora@novice chap04]$ sed -f sedlist1 datafile
northSSSSSS NW Charles Main 3.0 .98 3 34
SSSSSSern WE Sharon Gray 5.3 .97 5 23
southSSSSSS SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
是吧,果真當模式不匹配時只執行command2而:label後的命令沒有被執行,哈哈
e.g. 18
t: [address] t [label]
t-->test,若是在當前匹配的行上成功地進行了替換,那麼t命令就轉到標籤處或腳本末尾(未給定標籤默認指向腳本末尾)。
t要單獨成行
下面來一個簡單的例子:
[fedora@novice chap04]$ cat sedlist
/^s/d
/^west/s/west/QQQ/
t label1
/^n/y/nort/FUCK/
t label
:label
/^F/y/FUCK/nort/
:label1
/^QQQ/s/QQQ/west/
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW rharles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
[fedora@novice chap04]$ cat sedlist
/^s/d
/^west/y/Q/a/
t label1
/^n/y/nort/FUCK/
t label
:label
/^F/y/FUCK/nort/
:label1
/^n/y/FUCK/nort/
[fedora@novice chap04]$ sed -f sedlist datafile
northwest NW rharles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
看出二者的區別了麼?我相會的,嘿嘿