下面這些命令未必常常會用到,但當須要時,知道這些確定是件好事。shell
sed命令一般是對一行數據進行處理,而後下一行重複處理。ubuntu
sed編輯器包含了三個可用來處理多行文本的特殊命令bash
兩種刪除匹配的下一行的辦法:app
cat data1.txt This is the header line. This is a data line. This is the last line. sed '/^$/d' data1.txt This is the header line. This is a data line. This is the last line. sed '/header/{n ; d}' data1.txt This is the header line. This is a data line. This is the last line.
用大寫N,能夠一次性讀取兩行。區別與n是移動到下一行。編輯器
$ sed '/first/{ N ; s/\n/ / }' data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. $ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. $ cat data3.txt On Tuesday, the Linux System Administrator's group meeting will be held. All System Administrators should attend. Thank you for your attendance. $ sed 'N ; s/System.Administrator/Desktop User/' data3.txt On Tuesday, the Linux Desktop User's group meeting will be held. All Desktop Users should attend. Thank you for your attendance.
在N後面最好匹配多行命令,而單行命令則能夠放在N前面,如:ide
$ sed 'N > s/System\nAdministrator/Desktop\nUser/ > s/System Administrator/Desktop User/ > ' data4.txt On Tuesday, the Linux Desktop User's group meeting will be held. All System Administrators should attend. $ cat data4.txt On Tuesday, the Linux System Administrator's group meeting will be held. All System Administrators should attend. $ sed ' > s/System Administrator/Desktop User/ > N > s/System\nAdministrator/Desktop\nUser/ > ' data4.txt On Tuesday, the Linux Desktop User's group meeting will be held. All Desktop Users should attend.
若是在N後面用d,就會把多行都一塊兒刪除。可是若是用D,就會刪除到\n爲止。工具
$ sed 'N ; /System\nAdministrator/d' data4.txt All System Administrators should attend. $ cat data4.txt On Tuesday, the Linux System Administrator's group meeting will be held. All System Administrators should attend. $ sed 'N ; /System\nAdministrator/D' data4.txt Administrator's group meeting will be held. All System Administrators should attend.
而後有刪除header前的空白行測試
$ sed '/^$/{N ; /header/D}' data5.txt This is the header line. This is a date line. This is the last line. $ sed '{N ; /header/D}' data5.txt This is a date line. This is the last line. $ sed '{N ; /header/d}' data5.txt This is a date line. This is the last line. $ cat data5.txt This is the header line. This is a date line. This is the last line.
相似的和D類似的,P也是會和N配合輸出第一行this
$ cat data3.txt On Tuesday, the Linux System Administrator's group meeting will be held. All System Administrators should attend. Thank you for your attendance. $ sed -n 'N ; /System\nAdministrator/P' data3.txt On Tuesday, the Linux System
sed編輯器有一塊稱做保持空間的緩衝區域。在處理某些行時,能夠用保持空間來臨時保存一些行。spa
$ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. $ sed -n '/first/ {h ; p; n ; p ; g ; p }' data2.txt This is the first data line. This is the second data line. This is the first data line. $ sed -n '/first/ {h ; n ; p ; g ; p }' data2.txt This is the second data line. This is the first data line.
感嘆號命令(!)用來排除命令
$ sed -n '/header/!p' data2.txt This is the first data line. This is the second data line. This is the last line. $ sed 'N; > s/System\nAdministrator/Desktop\nUser/ > s/System Administrator/Desktop User/ > ' data4.txt On Tuesday, the Linux Desktop User's group meeting will be held. All System Administrators should attend. $ sed '$!N; > s/System\nAdministrator/Desktop\nUser/ > s/System Administrator/Desktop User/ > ' data4.txt On Tuesday, the Linux Desktop User's group meeting will be held. All Desktop Users should attend.
而後是將文件反轉的例子:
$ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. $ sed -n '{1!G ; h ; $p }' data2.txt This is the last line. This is the second data line. This is the first data line. This is the header line.
基於地址、地址模式或地址區間排除一整塊命令,這容許你只對數據流中的特定行執行一組命令。
分支命令b格式:[address]b [label]
address參數:決定了那些行的數據會觸發分支明林。
label參數:定義了要跳轉到的位置。
$ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. $ sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' data2.txt Is this the header test? This is the first data line. This is the second data line. Is this the last test?
上面的例子裏,分支跳過了2,3兩行。若是不想直接跳轉到腳本結尾,可爲分支命令定義一個要跳轉到的標籤。
標籤最多長7個字符,例子:
chen@ubuntu:~/shell/ch21$ sed '{/first/b jump1 ; s/This is the/No jump on/ > :jump1 > s/This is the/Jump here on/}' data2.txt No jump on header line. Jump here on first data line. No jump on second data line. No jump on last line. chen@ubuntu:~/shell/ch21$ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line.
若是文中出現first,程序就跳轉到jump1腳本行。若是沒有匹配,sed則會繼續執行腳本中的命令,包括分支標籤後的命令。
chen@ubuntu:~/shell/ch21$ echo "This, is, a, test, to, remove, commas." | sed -n '{ > :start > s/,//1p > b start > }' This is, a, test, to, remove, commas. This is a, test, to, remove, commas. This is a test, to, remove, commas. This is a test to, remove, commas. This is a test to remove, commas. This is a test to remove commas. ^C
要能中止循環,只要加上模式匹配在命令b前面就行了
chen@ubuntu:~/shell/ch21$ echo "This, is, a, test, to, remove, commas." | sed -n '{ > :start > s/,//1p > /,/b start > }' This is, a, test, to, remove, commas. This is a, test, to, remove, commas. This is a test, to, remove, commas. This is a test to, remove, commas. This is a test to remove, commas. This is a test to remove commas.
相似於分支命令,測試test命令(t)也能夠用來改變sed編輯器腳本執行流程。
若是天幻命令成功匹配並替換了一個模式,測試命令就會跳轉到指定標籤。若是替換命令未能匹配指定模式,測試命令就不會跳轉。
測試命令格式與分支命令格式相同:[address]t [label]
和分支命令同樣,若是沒有標籤的狀況下,若是測試成功,sed會跳轉到腳本結尾。
測試命令基本上就是一個if-then
chen@ubuntu:~/shell/ch21$ sed '{ > s/first/matched/ > t > s/This is the/No match on/ > }' data2.txt No match on header line. This is the matched data line. No match on second data line. No match on last line. chen@ubuntu:~/shell/ch21$ cat data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line.
測試命令的循環方法:
chen@ubuntu:~/shell/ch21$ echo "This, is, a, test, to, remove, commas." | sed -n '{ > :start > s/,//1p > t start > }' This is, a, test, to, remove, commas. This is a, test, to, remove, commas. This is a test, to, remove, commas. This is a test to, remove, commas. This is a test to remove, commas. This is a test to remove commas.
在使用通配符時,很難知道到底哪些文本會匹配模式。
chen@ubuntu:~/shell/ch21$ echo "The cat sleeps in his hat." | sed 's/cat/"cat"/'The "cat" sleeps in his hat. chen@ubuntu:~/shell/ch21$ echo "The cat sleeps in his hat." | sed 's/.at/".at"/g' The ".at" sleeps in his ".at".
用&符號能夠用來表明替換命令中的匹配的模式。無論匹配出來什麼樣的文本,均可以使用&符號,來使用這段文本。
myfly2@ubuntu:~/shell/ch21$ echo "The cat sleeps in his hat." | sed 's/.at/"&"/g' The "cat" sleeps in his "hat".
有時候咱們不須要整個字符串,只想提取字符串的一部分。
sed編輯器用圓括號來定義替換模式中的子模式,而後用特殊字符來引用每一個子模式。
chen@ubuntu:~/shell/ch21$ echo "The System Administrator manual" | sed ' > s/\(System\) Administrator/\1 User/' The System User manual chen@ubuntu:~/shell/ch21$ echo "The System Administrator manual" | sed ' s/System \(Administrator\)/\1 User/' The Administrator User manual chen@ubuntu:~/shell/ch21$ echo "That furry cat is pretty" | sed 's/furry \(.at\)/\1/' That cat is pretty chen@ubuntu:~/shell/ch21$ echo "That furry hat is pretty" | sed 's/furry \(.at\)/\1/' That hat is pretty #當須要在兩個或多個子模式間插入文本時,這個特性尤爲有用 chen@ubuntu:~/shell/ch21$ echo "1234567" | sed '{ > :start > s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/ > t start > }' 1,234,567 #分紅兩部分: #.*[0-9] #[0-9]{3} #第一個子模式是以數字結尾的任意長度的字符。 #第二個子模式是若干組三位數字
使用包裝腳本,sed腳本過程繁瑣,若是腳本很長的話。能夠將sed編輯器命令放到shell包裝腳本中。
這樣能夠不用每次都鍵入腳本。
chen@ubuntu:~/shell/ch21$ cat reverse.sh #!/bin/bash # Shell wrapper for sed editor script. # to reverse text file lines. # sed -n '{ 1!G ; h ; $p }' $1 # chen@ubuntu:~/shell/ch21$ chmod +x reverse.sh chen@ubuntu:~/shell/ch21$ ls data2.txt data4.txt reverse.sh chen@ubuntu:~/shell/ch21$ ./reverse.sh data2.txt This is the last line. This is the second data line. This is the first data line. This is the header line.
chen@ubuntu:~/shell/ch21$ cat fact.sh #!/bin/bash # Add commas to number in factorial answer # factorial=1 counter=1 number=$1 # while [ $counter -le $number ] do factorial=$[ $factorial * $counter ] counter=$[ $counter + 1 ] done # result=$(echo $factorial | sed '{ :start s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/ t start }') # echo "The result is $result" # chen@ubuntu:~/shell/ch21$ ./fact.sh 20 The result is 2,432,902,008,176,640,000
chen@ubuntu:~/shell/ch21$ sed 'G' data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line. chen@ubuntu:~/shell/ch21$ sed '$!G' data2.txt This is the header line. This is the first data line. This is the second data line. This is the last line.
#先刪除原來空行,而後再加空行 chen@ubuntu:~/shell/ch21$ sed '/^$/d;$!G' data6.txt This is line one. This is line two. This is line three. This is line four. chen@ubuntu:~/shell/ch21$
chen@ubuntu:~/shell/ch21$ sed '=' data2.txt 1 This is the header line. 2 This is the first data line. 3 This is the second data line. 4 This is the last line. chen@ubuntu:~/shell/ch21$ sed '=' data2.txt | sed 'N; s/\n/ /' 1 This is the header line. 2 This is the first data line. 3 This is the second data line. 4 This is the last line. chen@ubuntu:~/shell/ch21$ #=號命令增長行號 #N命令將兩行合併成一行 #而後把換行符換成空格
chen@ubuntu:~/shell/ch21$ sed '{ :start $q ; N ; 11,$D b start }' data7.txt This is line 6. This is line 7. This is line 8. This is line 9. This is line 10. This is line 11. This is line 12. This is line 13. This is line 14. This is line 15. chen@ubuntu:~/shell/ch21$ cat data7.txt This is line 1. This is line 2. This is line 3. This is line 4. This is line 5. This is line 6. This is line 7. This is line 8. This is line 9. This is line 10. This is line 11. This is line 12. This is line 13. This is line 14. This is line 15.
刪除不須要的空白行,若是有選擇的刪除空白行,須要一點創造力。
chen@ubuntu:~/shell/ch21$ sed '/./,/^$/!d' data8.txt This is line one. This is line two. This is line three. This is line four. chen@ubuntu:~/shell/ch21$ cat data8.txt This is line one. This is line two. This is line three. This is line four.
chen@ubuntu:~/shell/ch21$ cat data9.txt This is line one. This is line two. chen@ubuntu:~/shell/ch21$ sed '/./,$!d' data9.txt This is line one. This is line two.
1 chen@ubuntu:~/shell/ch21$ sed '{ 2 > :start 3 > /^\n*$/{$d ; N ; b start} 4 > }' data10.txt 5 This is the first line. 6 This is the seconde line. 7 chen@ubuntu:~/shell/ch21$ cat data10.txt 8 This is the first line. 9 This is the seconde line.
7.6 刪除HTML標籤