運維工做中sed常規操做命令梳理

 

sed是一個流編輯器(stream editor),一個非交互式的行編輯器。它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」,接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕;接着處理下一行,這樣不斷重複,直到文件末尾。文件內容並無改變,除非你使用重定向存儲輸出。sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操做;編寫轉換程序等。在平常的運維工程中,會時經常使用sed命令來處理行操做,下面根據工做中的使用經驗對sed的用法作一梳理:php

sed(stream editor)特徵:
1)流線型,非交互式的編輯器。它每次只處理一行文件並把輸出打印到屏幕上。
2)模式空間(Pattern space)即存放當前正在處理的行的緩存空間。 一旦處理工做完成,sed就會把結果輸出到屏幕,而後清空模式空間並把下一行讀入模式空間,進行相關處理;直到最後一行。
3)sed是無破壞性的,它能夠不更改原文件,除非使用重定向保存輸出結果或者使用特定生效參數(好比-i)。
4)對於一行文本,sed命令是依次執行的,若是有多個命令的話。這時,要注意各命令之間可能產生的相互影響。
5)對於多個sed命令,咱們能夠用「{}」把它們括起來。但要注意,右花括號必定要單獨成行。
6)能夠把一系列的sed命令寫入文件中並用sed的-f選項調用html

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選項shell

sed的相關命令:express

替換標誌:vim

sed支持的一些元字符:緩存

----------------------------------------------------------------------------------------------------------------------------
sed -n 'ap' filename 打印第a行
sed -n 'a,mp' filename 打印第a到m行
sed -n 'ap;mp' filename 打印第a行和第m行
sed -n '/wang/p' filename 打印包含wang字符的行
sed -n '3,$p' filename 打印第3到最後一行sass

sed -i 'nd' filename 刪除第n行
sed -i 'n,md' filename 刪除第n到m行
sed -i 'nd;md' filename 刪除第n行和第m行
sed -i '/wang/d' filename 刪除包含wang字符的行
sed -i '3,$d' filename 刪除第3到最後一行bash

sed -i 's/a/b/g' filename 將a替換成b,全文替換
sed -i 'ns/a/b/g' filename 將第行中的a替換成b
sed -i 'n,ms/a/b/g' filename 將第n到m行中的a替換成b
sed -i 'ns;ms/a/b/g' filename 將第n行和第m行中的a替換成b
sed -i '3,$s/a/b/g' filename 將第3到最後一行中的a替換成b
sed -i '/wang/s/a/b/g' filename 將包含wang字符的行中的a替換成bapp

sed的替換命令格式有三種:
1)s/A/B/g
2) s#A#B#g
3) s_A_B_g
g表示全局替換
例如:
將php.ini文件中的/Data/app/php5.5.1/lib/php/extensions/no-debug-non-zts-20121212/替換成/Data/app/php5.6.26/lib/php/extensions/no-debug-non-zts-20131226/
# sed -i 's#/Data/app/php5.5.1/lib/php/extensions/no-debug-non-zts-20121212/#/Data/app/php5.6.26/lib/php/extensions/no-debug-non-zts-20131226/#g' php.ini
----------------------------------------------------------------------------------------------------------------------------

sed經常使用到的幾個選項與參數解釋:
-n :使用安靜(silent)模式。在通常 sed 的用法中,全部來自 STDIN 的數據通常都會被列出到終端上。但若是加上 -n 參數後,則只有通過sed 特殊處理的那一行(或者動做)纔會被列出來。
-e :直接在命令列模式上進行 sed 的動做編輯;(加多個-e,表示能夠多點編輯)
-f :直接將 sed 的動做寫在一個文件內, -f filename 則能夠運行 filename 內的 sed 動做;
-r :sed 的動做支持的是延伸型正規表示法的語法。(默認是基礎正規表示法語法)
-i :直接修改讀取的文件內容,而不是輸出到終端。(這個很關鍵!)
動做說明:
a :新增, a 的後面能夠接字串,而這些字串會在新的一行出現(目前的下一行);
c :取代, c 的後面能夠接字串,這些字串能夠取代 多行 之間的內容;
d :刪除,由於是刪除啊,因此 d 後面一般不接任何內容;
i :插入, i 的後面能夠接字串,而這些字串會在新的一行出現(目前的上一行);
p :列印,亦即將某個選擇的數據印出。一般 p 會與參數 sed -n 一塊兒運行;
s :取代,能夠直接進行取代的工做。一般這個 s 的動做能夠搭配正規表示法;例如 sed -i '1,20s/old/new/g' filename 將第1行到20行的old替換爲new

要注意的是,sed 後面接的動做,最好以''單引號括住。固然用""雙引號也能夠。
若是使用單引號,那麼就沒辦法經過\’這樣來轉義,就有雙引號就能夠了,在雙引號內能夠用\」來轉義。

下面經過實例說明sed的用法:
1)以行爲單位的新增/刪除
將 /etc/passwd 的內容列出而且列印行號,同時,請將第 2~5 行刪除!
[root@www ~]# cat /etc/passwd | sed '2,5d'

只要刪除第2行
[root@www ~]# cat /etc/passwd | sed '2d'

要刪除第3到最後一行
[root@www ~]# cat /etc/passwd | sed '3,$d'

在第二行後(亦便是加在第三行)加上drink tea字樣!
[root@www ~]# cat /etc/passwd | sed '2a drink tea'

那若是是要在第二行前添加
[root@www ~]# cat /etc/passwd | sed '2i drink tea'

在匹配root的行的前面添加extension="huanqiu"
(-i參數表示直接在文件裏添加,而不是僅僅在終端輸出裏添加)
[root@www ~]# cat /etc/passwd | sed -i '/root/i extension="huanqiu"'

若是是要增長兩行以上,在第二行後面加入兩行字,例如『Drink tea or .....』與『drink beer?』
[root@www ~]# cat /etc/passwd | sed '2a Drink tea or ......\                //回車,添加第二行內容,每行之間用\隔開
> drink beer ?'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
注意:
每一行之間都必需要以反斜槓『 \ 』來進行新行的添加!
因此,上面的例子中,咱們能夠發如今第一行的最後面就有 \ 存在。

添加多行內容以下:

添加多行內容以下:
[root@www ~]# cat /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?\
> wangshibo\
> hahaha'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ......
drink beer ?
wangshibo
hahaha

若是多行之間不加\隔開,那麼就默認加到一行:
[root@www ~]# cat /etc/passwd | sed '2a Drink tea or ...... wangshibo'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
Drink tea or ...... wangshibo

2)以行爲單位的替換與顯示
將第2-5行的內容取代成爲『No 2-5 number』
[root@www ~]# cat /etc/passwd | sed '2,5c No 2-5 number'
透過這個方法咱們就可以將數據整行取代了!

僅列出 /etc/passwd 文件內的第 5-7 行
[root@www ~]# cat /etc/passwd | sed -n '5,7p'
能夠透過這個 sed 的以行爲單位的顯示功能, 就可以將某一個文件內的某些行號選擇出來顯示

3)數據的搜尋並顯示
搜索 /etc/passwd有root關鍵字的行
[root@www ~]# cat /etc/passwd | sed '/root/p'
若是root找到,除了輸出全部行,還會輸出匹配行。

使用-n的時候將只打印包含模板的行。
[root@www ~]# cat /etc/passwd | sed -n '/root/p'

4)數據的搜尋並刪除
刪除/etc/passwd全部包含root的行,其餘行輸出
[root@www ~]# cat /etc/passwd | sed '/root/d'

5)數據的搜尋並執行命令
找到匹配模式eastern的行後,執行後面花括號中的一組命令,每一個命令之間用分號分隔。
下面表示搜索匹配root的行後,把bash替換爲blueshell,再輸出這行:
[root@www ~]# cat /etc/passwd | sed -n '/root/{s/bash/blueshell/;p}'
1 root:x:0:0:root:/root:/bin/blueshell
若是隻替換/etc/passwd的第一個bash關鍵字爲blueshell,就退出

[root@www ~]# cat /etc/passwd | sed -n '/bash/{s/bash/blueshell/;p;q}'
1 root:x:0:0:root:/root:/bin/blueshell
最後的q是退出。

6)數據的搜尋並替換
除了整行的處理模式以外,sed 還能夠用行爲單位進行部分數據的搜尋並取代。基本上sed的搜尋與替代的與vi至關的相似!
它有點像這樣:
sed 's/要被取代的字串/新的字串/g'

先觀察原始信息,利用 /sbin/ifconfig 查詢 IP
[root@www ~]# /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:90:CC:A6:34:84
inet addr:192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::290:ccff:fea6:3484/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

將 IP 前面的部分予以刪除
[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g'
192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0

接下來則是刪除後續的部分,亦即: 192.168.1.100 Bcast:192.168.1.255 Mask:255.255.255.0
將 IP 後面的部分予以刪除
[root@www ~]# /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'
192.168.1.100

7)多點編輯(-e參數)
一條sed命令,刪除/etc/passwd第三行到末尾的數據,並把bash替換爲blueshell
[root@www ~]# cat /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
1 root:x:0:0:root:/root:/bin/blueshell
2 daemon:x:1:1:daemon:/usr/sbin:/bin/sh
-e表示多點編輯,第一個編輯命令刪除/etc/passwd第三行到末尾的數據,第二條命令搜索bash替換爲blueshell。

8)直接修改文件內容(危險動做)
sed 能夠直接修改文件的內容,沒必要使用管道命令或數據流重導向!
不過,由於這個動做會直接修改到原始的文件,因此請你千萬不要隨便拿系統配置來測試! 咱們仍是使用下載的 regular_express.txt 文件來測試看看吧!

利用sed將regular_express.txt 內每一行結尾若爲 . 則換成 !
[root@www ~]# sed -i 's/\.$/\!/g' regular_express.txt

利用sed直接在 regular_express.txt 最後一行加入『# This is a test』
[root@www ~]# sed -i '$a # This is a test' regular_express.txt

因爲$表明的是最後一行,而a的動做是新增,所以該文件最後新增『# This is a test』

sed的-i選項表示:能夠直接修改文件內容,這功能很是有幫助!
舉例來講,若是你有一個 100 萬行的文件,你要在第 100 行加某些文字,此時使用 vim 可能會瘋掉!由於文件太大了!
這個時候就能夠利用sed了,很是高效方面!!透過sed直接修改/取代的功能,甚至不須要使用vim去修訂了!

----------------------------------------------------------------------------------------------------------------------
如下是常常用到的一些sed操做
[root@www ~]# sed -e 's/123/1234/' a.txt
將a.txt文件中全部行中的123用1234替換(-e表示命令以命令行的方式執行;參數s,表示執行替換操做)

[root@www ~]# sed -e '3,5 a4' a.txt
將a.txt文件中的3行到5行之間全部行的後面添加一行內容爲4的行(參數a,表示添加行,參數a後面指定添加的內容)

[root@www ~]# sed -e '1s/12/45/' a.txt
把第一行的12替換成45(-e參數表示輸出結果到當前終端下,即只在輸出的結果中替換,其實文件裏並無真實生效;要使文件中的替換生效,需使用-i參數)

[root@www ~]# sed -i "s/oldstring/newstring/g" `grep oldstring -rl yourdir`
批量處理經過grep搜索出來的全部文檔,將這些文檔中全部的oldstring用newstring替換(-i參數表示直接對目標文件操做)

[root@www ~]# sed -n 's/^test/mytest/p' example.file
(-n)選項和p標誌一塊兒使用表示只打印那些發生替換的行。也就是說,若是某一行開頭的test被替換成mytest,就打印它。(^這是正則表達式中表示開頭,該符號後面跟的就是開頭的字符串)(參數p表示打印行)

[root@www ~]# sed 's/^wangpan/&19850715/' example.file
表示被替換換字符串被找到後,被替換的字符串經過&符號鏈接給出的字符串組成新字符傳替換被替換的字符串,全部以wangpan開頭的行都會被替換成它自已加19850715,變成wangpan19850715

[root@www ~]# sed -n 's/\(love\)able/\1rs/p' example.file
love被標記爲1,全部loveable會被替換成lovers,並且替換的行會被打印出來。須要將這條命令分解,s/是表示替換操做,\(love\)表示選中love字符串,\(love\)able/表示包含loveable的行,\(love\)able/\l表示love字符串標記爲1,表示在替換過程當中不變。rs/表示替換的目標字符串。這條命令的操做含義:只打印替換了的行

[root@www ~]# sed 's[root@www ~]#10[root@www ~]#100[root@www ~]#g' example.file
不論什麼字符,緊跟着s命令的都被認爲是新的分隔符,因此,「[root@www ~]#」在這裏是分隔符,代替了默認的「/」分隔符。表示把全部10替換成100。

[root@www ~]# sed -n '/love/,/unlove/p' example.file
只打印包含love字符串行到包含unlove字符串行之間的全部行(肯定行的範圍就是經過逗號實現的)

[root@www ~]# sed -n '5,/^wang/p' example
只打印從第五行開始到第一個包含以wang開始的行之間的全部行

[root@www ~]# sed '/love/,/unlove/s/[root@www ~]#/wangpan/' example.file
對於包含love字符串的行到包含unlove字符串之間的行,每行的末尾用字符串wangpan替換。
字符串[root@www ~]#/表示以字符串結尾的行,[root@www ~]#/表示每一行的結尾,s/[root@www ~]#/wangpan/表示每一行的結尾添加wangpan字符串

[root@www ~]# sed -e '11,53d' -e 's/wang/pan/' example.file
(-e)選項容許在同一行裏執行多條命令。如例子所示,第一條命令刪除11至53行,第二條命令用pan替換wang。命令的執行順序對結果有影響。若是兩個命令都是替換命令,那麼第一個替換命令將影響第二個替換命令的結果。(參數d,表示刪除指定的行)

[root@www ~]# sed --expression='s/wang/pan/' --expression='/love/d' example.file
一個比-e更好的命令是--expression。它能給sed表達式賦值。

[root@www ~]# sed '/wangpan/r file' example.file
file裏的內容被讀進來,顯示在與wangpan匹配的行後面,若是匹配多行,則file的內容將顯示在全部匹配行的下面。參數r,表示讀出文件,後面空格緊跟文件名稱

[root@www ~]# sed -n '/test/w file' example.file
在example.file中全部包含test的行都被寫入file裏。參數w,表示將匹配的行寫入到指定的文件file中

[root@www ~]# sed '/^test/a\oh! My god!' example.file
'oh! My god!'被追加到以test開頭的行的後面,sed要求參數a後面有一個反斜槓。

[root@www ~]# sed '/test/i\oh! My god!' example.file
'oh! My god!'被追加到包含test字符串行的前面,參數i表示添加指定內容到匹配行的前面,sed要求參數i後面有一個反斜槓

[root@www ~]# sed '/test/{ n; s/aa/bb/; }' example.file
若是test被匹配,則移動到匹配行的下一行,替換這一行的aa,變爲bb。參數n,表示讀取匹配行的下一個輸入行,用下一個命令處理新的行而不是匹配行。Sed要求參數n後跟分號

[root@www ~]# sed '1,10y/abcde/ABCDE/' example.file
把1—10行內全部abcde轉變爲大寫,注意,正則表達式元字符不能使用這個命令。參數y,表示把一個字符翻譯爲另外的字符(可是不用於正則表達式)

[root@www ~]# sed -i 's/now/right now/g' test_sed_command.txt

表示直接操做文件test_sed_command.txt,將文件test_sed_command.txt中全部的now用right now替換。參數-i,表示直接操做修改文件,不輸出。
[root@www ~]# sed '2q' test_sed_command.txt

在打印完第2行後,就直接退出sed。參數q,表示退出
[root@www ~]# sed -e '/old/h' -e '/girl-friend/G' test_sed_command.txt
首先了解參數h,拷貝匹配成功行的內容到內存中的緩衝區。在瞭解參數G,得到內存緩衝區的內容,並追加到當前模板塊文本的後面。上面命令行的含義:將包含old字符串的行的內容保存在緩衝區中,而後將緩衝區的內容拿出來添加到包含girl-friend字符串行的後面。隱含要求蒐集到緩衝區的匹配行在須要添加行的前面。

[root@www ~]# sed -e '/test/h' -e '/wangpan/x' example.file
將包含test字符串的行的內容保存在緩衝區中,而後再將緩衝區的內容替換包含wangpan字符串的行。參數x,表示行替換操做。隱含要求蒐集到緩衝區的匹配行在須要被替換行的前面。

若是sed在打印時不加-n參數,那麼打印多少行,其實就是在多少行下面打印這行內容,以下:
[root@www ~]# cat pets.txt
1111
222
3333
aaaa
bbb
vvvv
[root@www ~]# sed '3p' pets.txt
1111
222
3333
3333
aaaa
bbb
vvvv
[root@www ~]# sed '3p;5p' pets.txt
1111
222
3333
3333
aaaa
bbb
bbb
vvvv

把其中的my字符串替換成Hao Chen’s
注意:若是你要使用單引號,那麼你沒辦法經過\’這樣來轉義,就有雙引號就能夠了,在雙引號內能夠用\」來轉義。
[root@www ~]# sed "s/my/Hao Chen's/g" pets.txt

再注意:上面的sed並無對文件的內容改變,只是把處理事後的內容輸出,若是你要寫回文件,你可使用重定向,如:
[root@www ~]# sed "s/my/Hao Chen's/g" pets.txt > pets.txt
或使用 -i 參數直接修改文件內容:
[root@www ~]# sed -i "s/my/Hao Chen's/g" pets.txt

在每一行最前面加點東西,好比在每一行的前面添加#號或wang字符
[root@www ~]# sed 's/^/#/g' pets.txt
[root@www ~]# sed 's/^/wang/g' pets.txt
[root@www ~]# sed -i 's/^/wang/g' pets.txt //直接在文件中生效

在每一行最後面加點東西,好比在每一行的後面添加 --- 或者done字符
[root@www ~]# sed 's/$/ --- /g' pets.txt
[root@www ~]# sed 's/$/done/g' pets.txt

順便介紹一下正則表達式的一些最基本的東西:
^ 表示一行的開頭。如:/^#/ 以#開頭的匹配。
[root@www ~]# 表示一行的結尾。如:/}[root@www ~]#/ 以}結尾的匹配
\< 表示詞首。 如 \ 表示詞尾。 如 abc\> 表示以 abc 結尾的詞.
. 表示任何單個字符。
* 表示某個字符出現了0次或屢次。
[ ] 字符集合。 如:[abc]表示匹配a或b或c,還有[a-zA-Z]表示匹配全部的26個字符。若是其中有^表示反,如[^a]表示非a的字符

正規則表達式是一些很神奇的事,好比要去掉a.html文件中的tags:
[root@www ~]# cat a.html
<b>This</b> is what <span style="text-decoration: underline;">I</span> meant. Understand?

若是這樣搞的話,就會有問題
[root@www ~]# sed 's/<.*>//g' a.html
meant. Understand?

要解決上面的那個問題,就得像下面這樣。
其中的'[^>]' 指定了除了>的字符重複0次或屢次。
[root@www ~]# sed 's/<[^>]*>//g' a.html
This is what I meant. Understand?

只替換每一行的第一個s:
[root@www ~]# sed 's/s/S/1' my.txt

只替換每一行的第二個s:
[root@www ~]# sed 's/s/S/2' my.txt

只替換第一行的第3個之後的s:
[root@www ~]# sed 's/s/S/3g' my.txt

多個匹配
若是咱們須要一次替換多個模式,可參看下面的示例:(第一個模式把第一行到第三行的my替換成your,第二個則把第3行之後的This替換成了That)
[root@www ~]# sed '1,3s/my/your/g; 3,[root@www ~]#s/This/That/g' my.txt
上面的命令等價於:(注:下面使用的是sed的-e命令行參數)
[root@www ~]# sed -e '1,3s/my/your/g' -e '3,[root@www ~]#s/This/That/g' my.txt

可使用&來當作被匹配的變量,而後能夠在基本左右加點東西。以下所示:
[root@www ~]# cat b.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam
[root@www ~]# sed 's/my/[&]/g' b.txt
This is [my] cat, [my] cat's name is betty
This is [my] dog, [my] dog's name is frank
This is [my] fish, [my] fish's name is george
This is [my] goat, [my] goat's name is adam

圓括號匹配
使用圓括號匹配的示例:(圓括號括起來的正則表達式所匹配的字符串會能夠當成變量來使用,sed中使用的是\1,\2…)
[root@www ~]# sed 's/This is my \([^,]*\),.*is \(.*\)/\1:\2/g' b.txt
cat:betty
dog:frank
fish:george
goat:adam

上面這個例子中的正則表達式有點複雜,解開以下(去掉轉義字符):
正則爲:This is my ([^,]*),.*is (.*)
匹配爲:This is my (cat),……….is (betty)
而後:\1就是cat,\2就是betty

N命令:把下一行的內容歸入當成緩衝區作匹配。
下面的的示例會把原文本中的偶數行歸入奇數行匹配,而s只匹配並替換一次,因此,就成了下面的結果:
即匹配奇數行的替換,偶數行的不匹配:
[root@www ~]# vim a.txt
[root@www ~]# cat a.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
[root@wutao ~]# sed 'N;s/my/your/' a.txt
This is your cat
my cat's name is betty
This is your dog
my dog's name is frank
This is your fish
my fish's name is george
This is your goat
my goat's name is adam

也就是說,原來的文件成了:
This is my cat\n my cat's name is betty
This is my dog\n my dog's name is frank
This is my fish\n my fish's name is george
This is my goat\n my goat's name is adam

這樣一來,下面的例子你就明白了,
[root@www ~]# sed 'N;s/\n/,/' a.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

a命令和i命令
a命令就是append, i命令就是insert,它們是用來添加行的
其中的1i代表,其要在第1行前插入一行(insert)
[root@www ~]# cat a.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
[root@www ~]# sed "1 i This is my monkey, my monkey's name is wukong" a.txt
This is my monkey, my monkey's name is wukong
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

其中的1a代表,其要在最後一行後追加一行(append)
[root@www ~]# sed "$ a This is my monkey, my monkey's name is wukong" a.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
This is my monkey, my monkey's name is wukong

能夠運用匹配來添加文本:
注意其中的/fish/a,這意思是匹配到/fish/後就追加一行
[root@www~]# sed "/fish/a This is my monkey, my monkey's name is wukong" a.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
This is my monkey, my monkey's name is wukong
my fish's name is george
This is my monkey, my monkey's name is wukong
This is my goat
my goat's name is adam

下面這個例子是對每一行都挺插入:
[root@www ~]# sed "/my/a ----" a.txt
This is my cat
----
my cat's name is betty
----
This is my dog
----
my dog's name is frank
----
This is my fish
----
my fish's name is george
----
This is my goat
----
my goat's name is adam
----

c命令
c 命令是替換匹配行
[root@www ~]# sed "2 c This is my monkey, my monkey's name is wukong" a.txt
This is my cat
This is my monkey, my monkey's name is wukong
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

[root@www ~]# sed "/fish/c This is my monkey, my monkey's name is wukong" a.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my monkey, my monkey's name is wukong
This is my monkey, my monkey's name is wukong
This is my goat
my goat's name is adam

d命令
刪除匹配行
從一個模式到另外一個模式
[root@www ~]# sed -n '/dog/,/fish/p' my.txt
This is my dog, my dog's name is frank
This is my fish, my fish's name is george

從第一行打印到匹配fish成功的那一行
[root@www ~]# sed -n '1,/fish/p' my.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george

sed的Address
第一個是關於address,幾乎上述全部的命令都是這樣的(注:其中的!表示匹配成功後是否執行命令)
[address[,address]][!]{cmd}
address能夠是一個數字,也能夠是一個模式,你能夠經過逗號要分隔兩個address 表示兩個address的區間,參執行命令cmd,僞代碼以下:

[root@wutao ~]# cat b.txt
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam

其中的+3表示後面連續3行
[root@wutao ~]# sed '/dog/,+3s/^/# /g' b.txt
This is my cat, my cat's name is betty
# This is my dog, my dog's name is frank
# This is my fish, my fish's name is george
# This is my goat, my goat's name is adam

sed命令打包
第二個是cmd能夠是多個,它們能夠用分號分開,能夠用大括號括起來做爲嵌套命令。下面是幾個例子:
[root@wutao ~]# cat d.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam

對3行到第6行,執行命令/This/d
[root@wutao ~]# sed '3,6 {/This/d}' d.txt
This is my cat
my cat's name is betty
my dog's name is frank
my fish's name is george
This is my goat
my goat's name is adam

對3行到第6行,匹配/This/成功後,再匹配/fish/,成功後執行d命令
[root@wutao ~]# sed '3,6 {/This/{/fish/d}}' d.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
my fish's name is george
This is my goat
my goat's name is adam

從第一行到最後一行,若是匹配到This,則刪除之;若是前面有空格,則去除空格
[root@wutao ~]# sed '1,${/This/d;s/^ *//g}' d.txt
my cat's name is betty
my dog's name is frank
my fish's name is george
my goat's name is adam

sed的Hold Space
須要先了解一下Hold Space的概念,先來看四個命令:
g:將hold space中的內容拷貝到pattern space中,原來pattern space裏的內容清除
G:將hold space中的內容append到pattern space\n後
h:將pattern space中的內容拷貝到hold space中,原來的hold space裏的內容被清除
H:將pattern space中的內容append到hold space\n後
x:交換pattern space和hold space的內容

反序了一個文件的行(能夠直接用tac命令反序)
[root@www ~]# cat c.txt
11111
22222
33333
aaaaa
bbbbb
ccccc
[root@www ~]# sed '1!G;h;$!d' c.txt
ccccc
bbbbb
aaaaa
33333
22222
11111

其中的 ’1!G;h;$!d’ 可拆解爲三個命令:
1!G —— 只有第一行不執行G命令,將hold space中的內容append回到pattern space
h —— 第一行都執行h命令,將pattern space中的內容拷貝到hold space中
$!d —— 除了最後一行不執行d命令,其它行都執行d命令,刪除當前行

[root@www ~]# tac c.txt
ccccc
bbbbb
aaaaa
33333
22222
11111

找到以north開頭的行並在其後添加不少wang和huan,\n表示換行
[root@www ~]# cat e.txt
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
[root@www ~]# sed '/^north/a\FUCK FUCK FUCK FUCK \nkcuf kcuf kcuf kcuf' e.txt
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後是要帶\的,有時還要帶兩個。若是要添加的文本不止一行的話,除了最後一行每一行的結尾都要跟\。以上只是在控制檯輸入,在腳本中輸入的狀況仍是和書上說的同樣的。
--------------------------------------------------------------------------------------------------------

在以central開頭的行前分行插入FUCK
[root@www ~]# sed '/central/i\F\nU\nC\nK' e.txt
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

--------------------------------------------------------------------------------------------------------
通常,若是要添加的文本不止一行的話,除了最後一行每一行的結尾都要跟\。但在我這裏好像有點不同,在終端直接輸入時。
--------------------------------------------------------------------------------------------------------

把有sourth的行所有用FUCK取代
[root@www ~]# sed '/south/c\FUCK' e.txt
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

用FUCK替換全部以south開頭的行中的south.
[root@www ~]# sed '/^south/s/south/FUCK/g' e.txt
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

尋找大於1少於10的一位小數並用FUCK+&替代。這裏的&保存了前面的小數
[root@www ~]# sed 's/[0-9]\.[0-9]/FUCK&/' e.txt
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

p也會把匹配的行打印兩次。也就是說不使用-n選項的話,p會打印出匹配兩次
[root@www ~]# sed '/north/p' e.txt
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

P--多行打印:在執行完全部命令後模式空間的內容會自動輸出,在下面的例子中能夠看到匹配的行輸出了兩次,可是-n選項會抑制這個動做。只有在與D,N配合使用時纔會輸出模式空間裏的第一行,此時不用-n選項。
[root@www ~]# sed '/north/P' e.txt
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

多行刪除:選項看到d與D的不一樣之處了麼?其中空行分別爲1,2,3,4行。
[root@www ~]# cat g.txt
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
[root@www ~]# sed -e '/^$/N' -e '/^\n$/d' g.txt
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

[root@www ~]# sed -e '/^$/N' -e '/^\n$/D' g.txt
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會刪除兩個空行中的第一個,而後再讀入下一行,若是是空行則刪除第一行,若是空行後有文本則模式空間能夠正常輸出。
--------------------------------------------------------------------------------------------------------

r--從文件中讀取:從test中讀取相關的內容添加到e.txt中全部匹配的行的後面。
[root@www ~]# cat test
sssss
11111
[root@www ~]# cat e.txt
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

[root@www ~]# sed '/^south/r test' e.txt
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
sssss
11111
southern SO Suan Chin 5.1 .95 4 15
sssss
11111
southeast SE Patricia Hemenway 4.0 .7 4 17
sssss
11111
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

w--寫入文件:把e.txt中全部匹配的行寫入到test文件中
[root@www ~]# sed '/^south/w test' e.txt|cat test
sssss
11111
[root@www ~]# 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

n--next:若是有能匹配western行,則n命令使得sed讀取下一行,而後執行相應命令
[root@www ~]# cat e.txt
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

[root@www ~]# sed -e '/western/n' -e 's/SW/FUCK/' e.txt|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

y--變換:
[root@www ~]# sed '3,5y/s/S/' e.txt
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

[root@www ~]# sed '1y/3/9/' e.txt
northwest NW Charles Main 9.0 .98 9 94
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

--------------------------------------------------------------------------------------------------------
替換的類型要一致,數字與字母之間不能相互替換。
且對正則表達式的元字符不起做用。
--------------------------------------------------------------------------------------------------------

q--退出:
打印三行後退出
[root@www ~]# sed '3q' e.txt
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

用相應的字符作出替換後退出
[root@www ~]# sed -e 'y/northwest/ABCDEFGHI/' -e q e.txt
ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

或者
[root@www ~]# sed '{ y/northwest/ABCDEFGHI/; q;}' e.txt
ABCDEFGHD NW CEaClGH MaiA 3.0 .98 3 34

多個命令寫在一行時能夠用-e選項,也能夠用花括號把全部命令括起來並用分號隔開且最後一個分號無關緊要。

H/h/G/g--保存和取得
[root@www ~]# sed -e '/northeast/h' -e '$g' e.txt
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

[root@www ~]# sed -e '/northeast/h' -e '$G' e.txt
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
[root@www ~]# sed -e '/northeast/H' -e '$g' e.txt
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
[root@www ~]# sed -e '/northeast/H' -e '$G' e.txt
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的呢都是取代相應空間的內容,因此就有上面的不一樣結果。

x--交換模式/保持空間內容
首先匹配第一個包含north的行放入保持緩存,而後匹配第一個包含south的行放入模式空間,最後把二者的內容交換。
[root@www ~]# sed -e '/north/h' -e '/south/x' e.txt
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

--------------------------------sed腳本用法----------------------------------
[root@www ~]# cat e.txt
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

[root@www ~]# cat sedscripts
/central/a\
------This is a test--------
/northeast/i\
------This is a test too------

[root@www ~]# sed -f sedscripts e.txt
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--------

能夠在裏面添加註釋,以#開頭的行被認爲是註釋
若有多行,則每行都要以\結尾,除了最後一行。
以下面的腳本是能夠正常執行的。
[root@www ~]# cat sedscripts
#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 ------

[root@www ~]# sed -f sedscripts e.txt
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 ------
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 too--------
------Hi am here----------------

--------------------------------高級流控制命令--------------------------------
b 分支 :無條件轉移
t 測試 :有條件的轉移
它們將腳本中的控制轉移到包含特殊標籤的行;若是沒有標籤則直接轉移到腳本的末尾。只有當替換命令改變當前行時纔會被執行。

標籤:任意的字符組合且長度不大於7,它自己佔據一行且以冒號開頭
:mylabel
冒號和標籤之間不能有空格,標籤後的空格會被當作標籤的一部分。
標籤和命令之間容許有空格。

b 分支:[address] b [label]
b --> branch,在腳本中將控制權轉到另外一行,經過它你能夠跳到你想去的地方,是否是有點像c中的goto呀?
它能夠將一組命令當作一個過程來執行且這個過程在腳本中能夠重複執行,只要條件知足。

b--分支
匹配以north加空格開頭的行,若匹配則轉到:label後面的命令,在以s開頭的行前插入FFFFFFFFFFFFFFUCK ;
[root@wutao ~]# cat sedscripts
#This script is a test for sed commands
:label
/^s/i\
FFFFFFFFFFFFFFUCK
/^north / b label

[root@wutao ~]# sed -f sedscripts e.txt
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

其實這也是個循環,反覆執行兩個標籤間的命令,直到模式不匹配。可是,如上,無論匹配與否兩個標籤間的內容至少會被執行一次。
也就是說,正常狀況下上面的命令都會被執行一次。看下面的例子:
[root@wutao ~]# cat sedscripts
#This script is a test for sed commands
:label
/^n/d
/^A/b label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!

[root@wutao ~]# sed -f sedscripts e.txt
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語句有什麼異同?

若是匹配,什麼都不作,不然執行後的命令向以cent開頭的行後添加一些內容
[root@wutao ~]# cat sedscripts
#This script is a test for sed commands
:label
/^A/b label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!

[root@wutao ~]# sed -f sedscripts e.txt
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!!!

另外一種循環模式
command1
/pattern/b label
command2
label:
command3
首先執行command1,而後看模式是否匹配,若匹配則執行command3,不然執行command2,command3
[root@wutao ~]# cat sedscripts
#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!!!

[root@wutao ~]# sed -f sedscripts e.txt
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!!!

模式不匹配,順序執行各命令,下面來看匹配的狀況:
[root@wutao ~]# cat sedscripts
#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!!!

[root@wutao ~]# sed -f sedscripts e.txt
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後的命令的呀!這究竟是爲何呢?來看下一個腳本,只對上個腳本作一點點修改:
[root@wutao ~]# cat sedscripts
#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!!!
[root@wutao ~]# sed -f sedscripts e.txt
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看會有怎樣的結果:
[root@wutao ~]# cat sedscripts
#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!!!

[root@wutao ~]# sed -f sedscripts e.txt
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/ 被執行啦

又一個例子:
[root@wutao ~]# cat sedscripts
#This script is a test for sed commands
/^w/d
/^north/b label
p
:label
/^cent/a\
--FUCK!!! \
Just a test! \
Take it easy!!!

[root@wutao ~]# sed -f sedscripts e.txt
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開頭的全部行!再來一個例子:
[root@wutao ~]# cat sedscripts
#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!!!

[root@wutao ~]# sed -f sedscripts e.txt
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$
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$
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$
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$
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$
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的行 的操做纔會被跳過!

如何指定執行上例中的command2或command3中的一個
commmand1
/pattern/b label
command2
b
:label
command3
首先執行command1,而後執行/pattern/b label,若是模式匹配則直接跳到command3並執行相關命令,不然跳到command2在執行完相關命令後遇到分支b,分支b將控制轉到腳本的結尾,繞過了command3.
下面看一個簡單的例子:
[root@wutao ~]# cat sedscripts
#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!!!
[root@wutao ~]# sed -f sedscripts e.txt
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後的命令沒有被執行

t: [address] t [label]
t-->test,若是在當前匹配的行上成功地進行了替換,那麼t命令就轉到標籤處或腳本末尾(未給定標籤默認指向腳本末尾)。
t要單獨成行
下面來一個簡單的例子:
[root@wutao ~]# cat sedscripts
/^s/d
/^west/s/west/QQQ/
t label1
/^n/y/nort/FUCK/
t label
:label
/^F/y/FUCK/nort/
:label1
/^QQQ/s/QQQ/west/

[root@wutao ~]# sed -f sedscripts e.txt
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

[root@wutao ~]# cat sedscripts
/^s/d
/^west/y/Q/a/
t label1
/^n/y/nort/FUCK/
t label
:label
/^F/y/FUCK/nort/
:label1
/^n/y/FUCK/nort/

[root@wutao ~]# sed -f sedscripts e.txt northwest NW rharles Main 3.0 .98 3 34western WE Sharon Gray 5.3 .97 5 23eastern EA TB Savage 4.4 .84 5 20northeast NE AM Main Jr. 5.1 .94 3 13north NO Margot Weber 4.5 .89 5 9central CT Ann Stephens 5.7 .94 5 13

相關文章
相關標籤/搜索