1、-i選項使用的問題:
-i[suffix] (注意中間無空格)
sed -i在修改文件內容的時候,會先將原文件保存,保存的名稱為[原文件名][suffix]
例如:sed -i’.bak’ -i ‘s/aaa//g’/tmp/message
(1)第一個-i代表修改文件名的選項,第二個-i代表替換內容的選項
(2)-i’.bak’代表先將原文件改名為”原文件.bak”,然后依據原文件中的內容創建一個臨時文件,并在臨時文件中進行修改操作,并在流處理過程結束后將該臨時文件重命名為原文件名。(原文件名已經被備份,且以.bak后綴保存)
2、sed文本處理
在進行處理文本的時候,只知道在進行流處理的該行的行數,也就是說只有處理到文件的最后一行,sed才知道這行是最后一行,并且此時才會給這行打上$的標記。所以,用$-1來表示倒數第二行是錯誤的。(sed采用行號計數器來只是臨時記錄當前的行號)
3、sed -n ‘3,5!p’ filename
1、引號中的內容為,不打印3到5行的內容。(這一句其實包含了三層內容:1、3~5行不打?。?、其余的行都會打?。?、sed的默認autooutput還會再次將全文內容打印一次)
2、也就是說,如果不使用-n選項的話,該語句會將全文內容輸出兩遍,第一遍為p命令的輸出(不包含3~5行),第二遍為autooutput的輸出
示例:vim /tmp/message
#1 aaa
#2 bb
#3 ccd
#4 eee
#5 eeeeeeee
(1)如果使用sed -n ‘3,5!p’ /tmp/message的話會輸出如下內容:只顯示第1,2行內容
#1 aaa //p命令輸出的內容
#2 bb //p命令輸出的內容
(2)如果使用sed ‘3,5!p’ /tmp/message的話會輸出如下內容:
#1 aaa //p命令輸出的內容
#2 aaa //autooutput的輸出內容
#3 bb //p命令輸出的內容
#4 bb //autooutput的輸出內容
#5 ccd //autooutput的輸出內容
#6 eee //autooutput的輸出內容
#7 eeeeeee //autooutput的輸出內容
3、地址定界問題:
在進行地址定界匹配時,有時候會出現語法錯誤,可能就會導致不可預料的錯誤
(1)sed -n ‘/3,5/!p’ /tmp/message :如果按照上面的‘禁止輸出3到5行的內容’要求,并且使用這條語句的話,就會輸出如下內容:
#1 aaa
#2 bb
#3 ccd
#4 eee
#5 eeeeeeee
原因:引號中的內容表示的是在/tmp/message中找出“3,5”這個字符串所在的行,并且不輸出。而不是3-5行。
(2) 如果使用sed -n ‘3,8!p’ /tmp/message的話,就會輸出如下內容:
#1 aaa
#2 bb
原因:引號中的內容為不輸出3-8行的內容,但實際結果為文本只有5行,因此,只會顯示前面兩行,這個比較好理解。
(3) 使用sed -n ‘6,7!p’ /tmp/message的話,就會輸出以下內容:(輸出全文)
#1 aaa
#2 bb
#3 ccd
#4 eee
#5 eeeeeeee
原因:引號中的為不輸出6-7行的內容,實際情況是文本根本沒有6-7行,因此這個地址定界其實是無效的,相當于是說這個地址定界內容為空,sed會輸出全文的內容,因此就會輸出以上內容。
總結:
假設地址定界表達式為’a1,a2’,則sed會根據以下規則查找地址范圍:
(1)從文本的第一行開始,尋找第一個匹配a1的行:
能匹配到a1:假設第一個匹配a1的行為n1,則開始從n1+1行開始尋找匹配a2的行
能匹配到a2:假設第一次匹配到a2的行為n2,則文本就會以n1~n2為地址范圍,并且開始從n2+1開始再次搜索匹配a1的行,查找規則相同。
不能匹配到a2:不能匹配到a2的話,地址范圍就成為了n1~$,也就是說從n1到結尾,并且sed跳出循環查找。
不能匹配到a1:不能匹配a1的話,sed直接跳出循環查找,地址范圍為空。
(2)注意一些[!COMMAND]匹配地址范圍的用法。還是拿只有5行的/tmp/message來舉例。
a、’4,6!p’:4-6行不打印,也就是說1-3行打印
b、’6,7p’:只有6-7行打印,也就是說1-5行(全文)都不打印
(3)除了p命令外,其他很多命令都可以結合地址空間來進行豐富的操作。
(4)字符串匹配與行數匹配語法不同,字符串匹配使用’/a1/,/a2/’來表示,其地址范圍查找是與行數查找相同的。
4、刪除命令d的特性及使用:delete pattern space. start next cycle
特性:刪除模式空間的所有內容,并立即跳出script循環,進入下一個sed循環,即讀取下一行。
示例:
刪除/tmp/message中的第3行,并保存至文件:sed -i ‘3d’ /tmp/message
刪除/tmp/message中以‘#’號開頭的注釋行,但不刪除第一行的#!/bin/bash不能刪除:sed ‘/^#/{1!d}’ /tmp/message
sed -n ‘3d;3p’ message 是沒有輸出的,而sed -n ‘3d;2p’ message是有輸出的,因為刪除操作執行后,所有的對于這些已刪除的內容是無效的,只會從已刪除內容的下一行執行操作。
5、替換命令之y命令:將字符進行一一替換
示例:將message中包含有aaa,aaA,aAa,Aaa,AAa,aAA,AAA的字符串全部替換為aaa:也就是說只要包含了三個a的字符串,無論是什么情況都轉換為小寫的aaa字符串。
sed ‘y/AAA/aaa/’ message
6、替換命令之s命令:將匹配到的內容替換成指定內容
示例:
(1)刪除message中所有”#”開頭(可以包括前導空白)的注釋符號”#”,但第一行”#!/bin/bash”不處理。
sed -i ‘2,$s/^[\t]*#//’ /tmp/message,
也可以使用 sed ‘2,$s/^[[:space:]]\{0,\}#//’ /tmp/message
(2)在某行行首添加注釋#,sed -i ’90,s/^/#/’ filename
sed的buffer空間數據交換命令:h,H,g,G,x
特性:buffer也叫保持空間,初始狀態和模式空間一樣都是空的;無論是交換追加還是覆蓋,原空間的內容都不會改變。
保持空間的作用很大,它和模式空間之間的數據交換能實現很多看上去不能實現的功能,是實現sed高級功能所必須的,例如”窗口滑動”。同樣,這不是本文的內容。所以只簡單解釋這幾個命令的作用:
“h”命令:將當前模式空間中的內容覆蓋到保持空間。
“H”命令:在保持空間的尾部加上一個換行符”\n”,并將當前模式空間的內容追加到保持空間的尾部。
“g”命令:將保持空間的內容覆蓋到當前模式空間。
“G”命令:在模式空間的尾部加上一個換行符”\n”,并將當前保持空間的內容追加到模式空間的尾部。
“x”命令:交換模式空間和保持空間的內容。
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/92445