Shell文本處理三劍客之sed

本章大綱:

wKioL1h9oq_iOUcmAAA3mYNzK7I316.png

7.2 sed

流編輯器,過濾和替換文本。

工作原理:sed命令將當前處理的行讀入模式空間進行處理,處理完把結果輸出,並清空模式空間。然後再將下一行讀入模式空間進行處理輸出,以此類推,直到最後一行。還有一個空間叫保持空間,又稱暫存空間,可以暫時存放一些處理的數據,但不能直接輸出,只能放到模式空間輸出。

這兩個空間其實就是在內存中初始化的一個內存區域,存放正在處理的數據和臨時存放的數據。

Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

sed [選項] '地址 命令' file

選項

描述

-n 不打印模式空間
-e 執行腳本、表達式來處理
-f 腳本文件的內容添加到命令被執行
-i 修改原文件
-r 使用擴展正則表達式

 

命令

描述

s/regexp/replacement/ 替換字符串
p 打印當前模式空間
P 打印模式空間的第一行
d 刪除模式空間,開始下一個循環
D 刪除模式空間的第一行,開始下一個循環
= 打印當前行號
a \text 當前行追加文本
i \text 當前行上面插入文本
c \text 所選行替換新文本
q 立即退出sed腳本
r 追加文本來自文件
: label label爲b和t命令
b label 分支到腳本中帶有標籤的位置,如果分支不存在則分支到腳本的末尾
t label 如果s///是一個成功的替換,才跳轉到標籤
h H 複製/追加模式空間到保持空間
g G 複製/追加保持空間到模式空間
x 交換模式空間和保持空間內容
l 打印模式空間的行,並顯示控制字符$
n N 讀取/追加下一行輸入到模式空間
w filename 寫入當前模式空間到文件
! 取反、否定
& 引用已匹配字符串

 

地址

描述

first~step 步長,每step行,從第first開始
$ 匹配最後一行
/regexp/ 正則表達式匹配行
number 只匹配指定行
addr1,addr2 開始匹配addr1行開始,直接addr2行結束
addr1,+N 從addr1行開始,向後的N行
addr1,~N 從addr1行開始,到N行結束

藉助以下文本內容作爲示例講解:

# tail /etc/services
nimgtw         48003/udp               # Nimbus Gateway
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5           48129/tcp               # Bloomberg locator
blp5           48129/udp               # Bloomberg locator
com-bardac-dw     48556/tcp               # com-bardac-dw
com-bardac-dw     48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject

7.2.1 匹配打印(p)

1)打印匹配blp5開頭的行

# tail /etc/services |sed -n '/^blp5/p'
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator

2)打印第一行

# tail /etc/services |sed -n '1p'     
nimgtw          48003/udp               # Nimbus Gateway

3)打印第一行至第三行

# tail /etc/services |sed -n '1,3p'
nimgtw          48003/udp               # Nimbus Gateway
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services

4)打印奇數行

# seq 10 |sed -n '1~2p'
1
3
5
7
9

5)打印匹配行及後一行

# tail /etc/services |sed -n '/blp5/,+1p'
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator

6)打印最後一行

# tail /etc/services |sed -n '$p' 
iqobject        48619/udp               # iqobject

7)不打印最後一行

# tail /etc/services |sed -n '$!p'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject

感嘆號也就是對後面的命令取反。

8)匹配範圍

# tail /etc/services  |sed -n '/^blp5/,/^com/p'
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw

匹配開頭行到最後一行:

# tail /etc/services |sed -n '/blp5/,$p'
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject

以逗號分開兩個樣式選擇某個範圍。

9)引用系統變量,用引號

# a=1
# tail /etc/services |sed -n ''$a',3p'
或
# tail /etc/services |sed -n "$a,3p"

sed命令用單引號時,裏面變量用單引號引起來,或者sed命令用雙引號,因爲雙引號解釋特殊符號原有意義。

7.2.2 匹配刪除(d)

# tail /etc/services |sed '/blp5/d'
nimgtw          48003/udp               # Nimbus Gateway
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
# tail /etc/services |sed '1d'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
# tail /etc/services |sed '1~2d'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/udp               # iqobject
# tail /etc/services |sed '1,3d'
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject

 

去除空格http.conf文件空行或開頭#號的行:

# sed '/^#/d;/^$/d' /etc/httpd/conf/httpd.conf

刪除與打印使用方法類似,可以理解是打印的取反。不用-n選項。

7.2.3 替換(s///)

1)替換blp5字符串爲test

# tail /etc/services |sed 's/blp5/test/'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test            48129/tcp               # Bloomberg locator
test            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker
全局替換加g:
# tail /etc/services |sed 's/blp5/test/g'

2)替換開頭是blp5的字符串並打印

# tail /etc/services |sed -n 's/^blp5/test/p'
test            48129/tcp               # Bloomberg locator
test            48129/udp               # Bloomberg locator

3)使用&命令引用匹配內容並替換

# tail /etc/services |sed 's/48049/&.0/'
3gpp-cbsp       48049.0/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker
IP加單引號:
# echo '10.10.10.1 10.10.10.2 10.10.10.3' |sed -r 's/[^ ]+/"&"/g'
"10.10.10.1" "10.10.10.2" "10.10.10.3"

4)對1-4行的blp5進行替換

# tail /etc/services | sed '1,4s/blp5/test/'                   
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

5)對匹配行進行替換

# tail /etc/services | sed '/48129\/tcp/s/blp5/test/'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

6)二次匹配替換

# tail /etc/services  |sed 's/blp5/test/;s/3g/4g/'
4gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test            48129/tcp               # Bloomberg locator
test            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

7)分組使用,在每個字符串後面添加123

# tail /etc/services |sed -r 's/(.*) (.*)(#.*)/\1\2test \3/'
3gpp-cbsp       48049/tcp              test # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp              test # Image Systems Network Services
isnetserv       48128/udp              test # Image Systems Network Services
blp5            48129/tcp              test # Bloomberg locator
blp5            48129/udp              test # Bloomberg locator
com-bardac-dw   48556/tcp              test # com-bardac-dw
com-bardac-dw   48556/udp              test # com-bardac-dw
iqobject        48619/tcp              test # iqobject
iqobject        48619/udp              test # iqobject
matahari        49000/tcp              test # Matahari Broker

將不變的字符串匹配分組,剩餘就是要替換的,再反向引用。

8)將協議與端口號位置調換

# tail /etc/services |sed -r 's/(.*)(\<[0-9]+\>)\/(tcp|udp)(.*)/\1\3\/\2\4/'
3gpp-cbsp       tcp/48049               # 3GPP Cell Broadcast Service Protocol
isnetserv       tcp/48128               # Image Systems Network Services
isnetserv       udp/48128               # Image Systems Network Services
blp5            tcp/48129               # Bloomberg locator
blp5            udp/48129               # Bloomberg locator
com-bardac-dw   tcp/48556               # com-bardac-dw
com-bardac-dw   udp/48556               # com-bardac-dw
iqobject        tcp/48619               # iqobject
iqobject        udp/48619               # iqobject
matahari        tcp/49000               # Matahari Broker

9)位置調換

# echo "abc:cde;123:456" |sed -r 's/([^:]+)(;.*:)([^:]+$)/\3\2\1/'
abc:456;123:cde

10)註釋匹配行後的多少行

# seq 10 |sed '/5/,+3s/^/#/'
1
2
3
4
#5
#6
#7
#8
9
10

11)去除開頭和結尾空格或製表符

# echo "  1 2 3  " |sed 's/^[ \t]*//;s/[ \t]*$//'
1 2 3

7.2.4 多重編輯(-e)

# tail /etc/services |sed -e '1,2d' -e 's/blp5/test/'
isnetserv       48128/udp               # Image Systems Network Services
test            48129/tcp               # Bloomberg locator
test            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker
也可以使用分號分隔:
# tail /etc/services |sed '1,2d;s/blp5/test/'

7.2.5 添加新內容(a、i和c)

1)在blp5上一行添加test

# tail /etc/services |sed '/blp5/i \test'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test
blp5            48129/tcp               # Bloomberg locator
test
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

2)在blp5下一行添加test

# tail /etc/services |sed '/blp5/a \test'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
test
blp5            48129/udp               # Bloomberg locator
test
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

3)將blp5替換新行

# tail /etc/services |sed '/blp5/c \test'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
test
test
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

4)在指定行下一行添加一行

# tail /etc/services |sed '2a \test'     
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
test
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

5)在指定行前面和後面添加一行

# seq 5 |sed '3s/.*/txt\n&/' 
1
2
txt
3
4
5
# seq 5 |sed '3s/.*/&\ntxt/'
1
2
3
txt
4
5

7.2.6 讀取文件並追加到匹配行後(r)

# cat a.txt
123
456
# tail /etc/services |sed '/blp5/r a.txt'         
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
123
456
blp5            48129/udp               # Bloomberg locator
123
456
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker

7.2.7 將匹配行寫到文件(w)

# tail /etc/services |sed '/blp5/w b.txt'
3gpp-cbsp       48049/tcp               # 3GPP Cell Broadcast Service Protocol
isnetserv       48128/tcp               # Image Systems Network Services
isnetserv       48128/udp               # Image Systems Network Services
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator
com-bardac-dw   48556/tcp               # com-bardac-dw
com-bardac-dw   48556/udp               # com-bardac-dw
iqobject        48619/tcp               # iqobject
iqobject        48619/udp               # iqobject
matahari        49000/tcp               # Matahari Broker
# cat b.txt
blp5            48129/tcp               # Bloomberg locator
blp5            48129/udp               # Bloomberg locator

 

7.2.8 讀取下一行(n和N

n命令的作用是讀取下一行到模式空間。

N命令的作用是追加下一行內容到模式空間,並以換行符\n分隔。

1)打印匹配的下一行

# seq 5 |sed -n '/3/{n;p}'                             
4

2)打印偶數

# seq 6 |sed -n 'n;p'  
2
4
6

 

sed先讀取第一行1,執行n命令,獲取下一行2,此時模式空間是2,執行p命令,打印模式空間。 現在模式空間是2,sed再讀取3,執行n命令,獲取下一行4,此時模式空間爲4,執行p命令,以此類推。

3)打印奇數

# seq 6 |sed 'n;d'    
1
3
5

sed先讀取第一行1,此時模式空間是1,並打印模式空間1,執行n命令,獲取下一行2,執行d命令,刪除模式空間的2,sed再讀取3,此時模式空間是3,並打印模式空間,再執行n命令,獲取下一行4,執行d命令,刪除模式空間的3,以此類推。

4)每三行執行一次p命令

# seq 6 |sed 'n;n;p'   
1
2
3
3
4
5
6
6

sed先讀取第一行1,並打印模式空間1,執行n命令,獲取下一行2,並打印模式空間2,再執行n命令,獲取下一行3,執行p命令,打印模式空間3。sed讀取下一行3,並打印模式空間3,以此類推。

5)每三行替換一次

方法1:

# seq 6 |sed 'n;n;s/^/=/;s/$/=/'
1
2
=3=
4
5
=6=

我們只是把p命令改成了替換命令。

方法2:

這次用到了地址匹配,來實現上面的效果:

# seq 6 |sed '3~3{s/^/=/;s/$/=/}'
1
2
=3=
4
5
=6=

當執行多個sed命令時,有時相互會產生影響,我們可以用大括號{}把他們括起來。

6)再看下N命令的功能

# seq 6 |sed 'N;q'
1
2
將兩行合併一行:
# seq 6 |sed 'N;s/\n//'
12
34
56

第一個命令:sed讀取第一行1,N命令讀取下一行2,並以\n2追加,此時模式空間是1\n2,再執行q退出。

爲了進一步說明N的功能,看第二個命令:執行N命令後,此時模式空間是1\n2,再執行把\n替換爲空,此時模式空間是12,並打印。

# seq 5 |sed -n 'N;p'
1
2
3
4
# seq 6 |sed -n 'N;p'
1
2
3
4
5
6

爲什麼第一個不打印5呢?

因爲N命令是讀取下一行追加到sed讀取的當前行,當N讀取下一行沒有內容時,則退出,也不會執行p命令打印當前行。

當行數爲偶數時,N始終就能讀到下一行,所以也會執行p命令。

7)打印奇數行數時的最後一行

# seq 5 |sed -n '$!N;p'           
1
2
3
4
5

加一個滿足條件,當sed執行到最後一行時,用感嘆號不去執行N命令,隨後執行p命令。

7.2.9 打印和刪除模式空間第一行(P和D)

P命令作用是打印模式空間的第一行。

D命令作用是刪除模式空間的第一行。

1)打印奇數

# seq 6 |sed -n 'N;P'
1
3
5

2)保留最後一行

# seq 6 |sed 'N;D'       
6

 

讀取第一行1,執行N命令讀取下一行並追加到模式空間,此時模式空間是1\n2,執行D命令刪除模式空間第一行1,剩餘2。

讀取第二行,執行N命令,此時模式空間是3\n4,執行D命令刪除模式空間第一行3,剩餘4。

以此類推,讀取最後一行打印時,而N獲取不到下一行則退出,不再執行D,因此模式空間只剩餘6就打印。

7.2.10 保持空間操作(h與H、g與G和x)

h命令作用是複製模式空間內容到保持空間(覆蓋)。

H命令作用是複製模式空間內容追加到保持空間。

g命令作用是複製保持空間內容到模式空間(覆蓋)。

G命令作用是複製保持空間內容追加到模式空間。

x命令作用是模式空間與保持空間內容互換

1)將匹配的內容覆蓋到另一個匹配

# seq 6 |sed -e '/3/{h;d}' -e '/5/g'
1
2
4
3
6

h命令把匹配的3複製到保持空間,d命令刪除模式空間的3。後面命令再對模式空間匹配5,並用g命令把保持空間3覆蓋模式空間5。

2)將匹配的內容放到最後

# seq 6 |sed -e '/3/{h;d}' -e '$G'
1
2
4
5
6
3

3)交換模式空間和保持空間

# seq 6 |sed -e '/3/{h;d}' -e '/5/x' -e '$G'
1
2
4
3
6
5

看後面命令,在模式空間匹配5並將保持空間的3與5交換,5就變成了3,。最後把保持空間的5追加到模式空間的。

4)倒敘輸出

# seq 5 |sed '1!G;h;$!d'
5
4
3
2
1

分析下:

1!G 第一行不執行把保持空間內容追加到模式空間,因爲現在保持空間還沒有數據。

h 將模式空間放到保持空間暫存。

$!d 最後一行不執行刪除模式空間的內容。

讀取第一行1時,跳過G命令,執行h將模式空間1複製到保持空間,執行d命令刪除模式空間的1。

讀取第二行2時,模式空間是2,執行G命令,將保持空間1追加到模式空間,此時模式空間是2\n1,執行h將2\n1覆蓋到保持空間,d刪除模式空間。

讀取第三行3時,模式空間是3,執行G命令,將保持空間2\n1追加到模式空間,此時模式空間是3\n2\n1,執行h將模式空間內容複製到保持空間,d刪除模式空間。

以此類推,讀到第5行時,模式空間是5,執行G命令,將保持空間的4\n3\n2\n1追加模式空間,然後複製到模式空間,5\n4\n3\n2\n1,不執行d,模式空間保留,輸出。

由此可見,每次讀取的行先放到模式空間,再複製到保持空間,d命令刪除模式空間內容,防止輸出,再追加到模式空間,因爲追加到模式空間,會追加到新讀取的一行的後面,循環這樣操作, 就把所有行一行行追加到新讀取行的後面,就形成了倒敘。

5)每行後面添加新空行

# seq 10 |sed G
1

2

3

4

5

7.2.11 標籤

標籤可以控制流,實現分支判斷。

: lable name  定義標籤

b lable  跳轉到指定標籤,如果沒有標籤則到腳本末尾

t lable  跳轉到指定標籤,前提是s///命令執行成功

1)將換行符替換成逗號

方法1:

# seq 6 |sed 'N;s/\n/,/'
1,2
3,4
5,6

這種方式並不能滿足我們的需求,每次sed讀取到模式空間再打印是新行,替換\n也只能對N命令追加後的1\n2這樣替換。

這時就可以用到標籤了:

# seq 6 |sed ':a;N;s/\n/,/;b a'           
1,2,3,4,5,6

看看這裏的標籤使用,:a 是定義的標籤名,b a是跳轉到a位置。

sed讀取第一行1,N命令讀取下一行2,此時模式空間是1\n2$,執行替換,此時模式空間是1,2$,執行b命令再跳轉到標籤a位置繼續執行N命令,讀取下一行3追加到模式空間,此時模式空間是1,2\n3$,再替換,以此類推,不斷追加替換,直到最後一行N讀不到下一行內容退出。

方法2:

# seq 6 |sed ':a;N;$!b a;s/\n/,/g'
1,2,3,4,5,6

先將每行讀入到模式空間,最後再執行全局替換。$!是如果是最後一行,則不執行b a跳轉,最後執行全局替換。

# seq 6 |sed ':a;N;b a;s/\n/,/g'
1
2
3
4
5
6

可以看到,不加$!是沒有替換,因爲循環到N命令沒有讀到行就退出了,後面的替換也就沒執行。

2)每三個數字加個一個逗號

# echo "123456789" |sed -r 's/([0-9]+)([0-9]+{3})/\1,\2/'
123456,789
# echo "123456789" |sed -r ':a;s/([0-9]+)([0-9]+{3})/\1,\2/;t a'
123,456,789
# echo "123456789" |sed -r ':a;s/([0-9]+)([0-9]+{2})/\1,\2/;t a'
1,23,45,67,89

執行第一次時,替換最後一個,跳轉後,再對123456匹配替換,直到匹配替換不成功,不執行t命令。

7.2.12 忽略大小寫匹配

# echo -e "a\nA\nb\nc" |sed 's/a/1/Ig'
1
1
b
c

7.2.13 獲取總行數

# seq 10 |sed -n '$='
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章