1. 程式人生 > >shell指令碼中sed的使用詳解

shell指令碼中sed的使用詳解

sed是一個很好的檔案處理工具,本身是一個管道命令,主要是以行為單位進行處理,可以將資料行進行替換、刪除、新增、選取等特定工作,下面先了解一下sed的用法
sed命令列格式為:
         sed [-nefri] ‘command’ 輸入文字        

常用選項:
        -n∶使用安靜(silent)模式。在一般 sed 的用法中,所有來自 STDIN的資料一般都會被列出到螢幕上。但如果加上 -n 引數後,則只有經過sed 特殊處理的那一行(或者動作)才會被列出來。

        -e∶多點編輯,允許多個指令碼指令被執行。
        -r∶支援擴充套件正則+ ? () {} |
        -f∶直接將 sed 的動作寫在一個檔案內, -f filename 則可以執行 filename 內的sed 動作;
        -i∶直接修改讀取的檔案內容,而不是由螢幕輸出。      


命令選項:
    p   列印匹配行                           
    =   顯示檔案行號                        
    a/  在定位行號後附加新文字資訊            
    i/  在定位行號後插入新文字資訊          
    d   刪除定位行                          
    l   顯示與八進位制ASCII程式碼等價的控制字元    
    n   從另一個文字中讀文字下一行,並附加在下一行   
    g   將模式2貼上到/pattern n/
    c/  用新文字替換定位文字
    s   使用替換模式替換相應模式
    r   從另一個文字中讀文字
    w   寫文字到一個檔案
    q   第一個模式匹配完成後退出或立即退出
    y   傳送字元
    {}  在定位行執行的命令組

正則表示式元字元:

 與grep一樣,sed也支援特殊元字元,來進行模式查詢、替換。不同的是,sed使用的正則表示式是括在斜槓線"/"之間的模式。

 元字元  功能  示例
 ^  行首定位符  /^my/  匹配所有以my開頭的行
 $  行尾定位符  /my$/  匹配所有以my結尾的行
 .  匹配除換行符以外的單個字元  /m..y/  匹配包含字母m,後跟兩個任意字元,再跟字母y的行
 *  匹配零個或多個前導字元  /my*/  匹配包含字母m,後跟零個或多個y字母的行
 []  匹配指定字元組內的任一字元  /[Mm]y/  匹配包含My或my的行
 [^]
 匹配不在指定字元組內的任一字元  /[^Mm]y/  匹配包含y,但y之前的那個字元不是M或m的行
 ..  儲存已匹配的字元  1,20s/youself/\1r/  標記元字元之間的模式,並將其儲存為標籤1,之後可以使用\1來引用它。最多可以定義9個標籤,從左邊開始編號,最左邊的是第一個。此例中,對第1到第20行進行處理,you被儲存為標籤1,如果發現youself,則替換為your。
 &  儲存查詢串以便在替換串中引用  s/my/**&**/  符號&代表查詢串。my將被替換為**my**
 \<  詞首定位符  /\<my/  匹配包含以my開頭的單詞的行
 \>  詞尾定位符  /my\>/  匹配包含以my結尾的單詞的行
 x\{m\}  連續m個x  /9\{5\}/ 匹配包含連續5個9的行
 x\{m,\}  至少m個x  /9\{5,\}/  匹配包含至少連續5個9的行
 x\{m,n\}  至少m個,但不超過n個x  /9\{5,7\}/  匹配包含連續5到7個9的行

sed替換的基本語法為:

sed 's/原字串/替換字串/'


單引號裡面,s表示替換,三根斜線中間是替換的樣式,特殊字元需要使用反斜線”\”進行轉義,但是單引號”‘”是沒有辦法用反斜線”\”轉義的,這時候只要把命令中的單引號改為雙引號就行了,例如:

sed "s/原字串包含'/替換字串包含'/" //要處理的字元包含單引號


命令中的三根斜線分隔符可以換成別的符號,這在要替換的內容有較多斜線是較為方便,只需要緊跟s定義即可,例如換成問號”?”:

sed 's?原字串?替換字串?' //自定義分隔符為問號


可以在末尾加g替換每一個匹配的關鍵字,否則只替換每行的第一個,例如:

sed 's/原字串/替換字串/' //替換所有匹配關鍵字


上箭頭”^”表示行首,美元”$”符號如果在引號中表示行尾,但是在引號外卻表示末行(最後一行),這裡犯二了,搜了半天哪個符號表示首行,半天才想起來,首行就是數字”1″啊.那麼在行首和行尾新增字串就是把行尾和行首替換,例如:

sed 's/^/新增的頭部&/g' //在所有行首新增
sed 's/$/&新增的尾部/g' //在所有行末新增
sed '2s/原字串/替換字串/g' //替換第2行
sed '$s/原字串/替換字串/g' //替換最後一行
sed '2,5s/原字串/替換字串/g' //替換2到5行
sed '2,$s/原字串/替換字串/g' //替換2到最後一行


替換樣式可以多個在同一條命令中執行,用分號”;”分隔,例如:

sed 's/^/新增的頭部&/g;s/$/&新增的尾部/g' //同時執行兩個替換規則


sed處理過的輸出是直接輸出到螢幕上的,要儲存可以將輸出重定向,或者使用引數”i”直接在檔案中替換:

sed -i 's/原字串/替換字串/g' filename //替換檔案中的所有匹配項
1.1 p命令 命令p用於顯示模式空間的內容。預設情況下,sed把輸入行列印在螢幕上,選項-n用於取消預設的列印操作。當選項-n和命令p同時出現時,sed可列印選定的內容。

sed '/my/p' datafile
#預設情況下,sed把所有輸入行都列印在標準輸出上。如果某行匹配模式my,p命令將把該行另外列印一遍。


sed -'/my/p' datafile
#選項-n取消sed預設的列印,p命令把匹配模式my的行列印一遍。

1.2 d命令

命令d用於刪除輸入行。sed先將輸入行從檔案複製到模式空間裡,然後對該行執行sed命令,最後將模式空間裡的內容顯示在螢幕上。如果發出的是命令d,當前模式空間裡的輸入行會被刪除,不被顯示。

sed '$d' datafile
#刪除最後一行,其餘的都被顯示

sed '/my/d' datafile
#刪除包含my的行,其餘的都被顯示

1.3 s命令

sed 's/^My/You/g' datafile
#命令末端的g表示在行內進行全域性替換,也就是說如果某行出現多個My,所有的My都被替換為You。

sed -'1,20s/My$/You/gp' datafile
#取消預設輸出,處理1到20行裡匹配以My結尾的行,把行內所有的My替換為You,並列印到螢幕上。

sed 's#My#Your#g' datafile
#緊跟在s命令後的字元就是查詢串和替換串之間的分隔符。分隔符預設為正斜槓,但可以改變。
無論什麼字元(換行符、反斜線除外),只要緊跟s命令,就成了新的串分隔符。

1.4 e選項

-e是編輯命令,用於sed執行多個編輯任務的情況下。在下一行開始編輯前,所有的編輯動作將應用到模式緩衝區中的行上。

sed -'1,10d' -'s/My/Your/g' datafile

#選項-e用於進行多重編輯。第一重編輯刪除第1-3行。第二重編輯將出現的所有My替換為Your。因為是逐行進行這兩項編輯(即這兩個命令都在模式空間的當前行上執行),所以編輯命令的順序會影響結果。

1.5 r命令

r命令是讀命令。sed使用該命令將一個文字檔案中的內容加到當前檔案的特定位置上。

sed '/My/r introduce.txt' datafile
#如果在檔案datafile的某一行匹配到模式My,就在該行後讀入檔案introduce.txt的內容。如果出現My的行不止一行,則在出現My的各行後都讀入introduce.txt檔案的內容。

1.6 w命令

sed -'/hrwang/w me.txt' datafile

1.7 a\ 命令

a\ 命令是追加命令,追加將新增新文字到檔案中當前行(即讀入模式緩衝區中的行)的後面。所追加的文字行位於sed命令的下方另起一行。如果要追加的內容超過一行,則每一行都必須以反斜線結束,最後一行除外。最後一行將以引號和檔名結束。

sed '/^hrwang/a\
>hrwang and mjfan are husband\
>and wife'
 datafile
#如果在datafile檔案中發現匹配以hrwang開頭的行,則在該行下面追加hrwang and mjfan are husband and wife

1.8 i\ 命令

i\ 命令是在當前行的前面插入新的文字。

1.9 c\ 命令

sed使用該命令將已有文字修改成新的文字。

1.10 n命令

sed使用該命令獲取輸入檔案的下一行,並將其讀入到模式緩衝區中,任何sed命令都將應用到匹配行緊接著的下一行上。

sed '/hrwang/{n;s/My/Your/;}' datafile

注:如果需要使用多條命令,或者需要在某個地址範圍內巢狀地址,就必須用花括號將命令括起來,每行只寫一條命令,或這用分號分割同一行中的多條命令。 1.11 y命令 該命令與UNIX/Linux中的tr命令類似,字元按照一對一的方式從左到右進行轉換。例如,y/abc/ABC/將把所有小寫的a轉換成A,小寫的b轉換成B,小寫的c轉換成C。

sed '1,20y/hrwang12/HRWANG^$/' datafile
#將1到20行內,所有的小寫hrwang轉換成大寫,將1轉換成^,將2轉換成$
#正則表示式元字元對y命令不起作用。與s命令的分隔符一樣,斜線可以被替換成其它的字元。

1.12 q命令

q命令將導致sed程式退出,不再進行其它的處理。

sed '/hrwang/{s/hrwang/HRWANG/;q;}' datafile

1.13 h命令和g命令

#cat datafile

My name is hrwang.

Your name is mjfan.

hrwang is mjfan's husband.

mjfan is hrwang's wife.

sed -'/hrwang/h' -'$G' datafile

sed -e '/hrwang/H' -e '$G' datafile

#通過上面兩條命令,你會發現h會把原來暫存緩衝區的內容清除,只儲存最近一次執行h時儲存進去的模式空間的內容。而H命令則把每次匹配hrwnag的行都追加儲存在暫存緩衝區。

sed -e '/hrwang/H' -e '$g' datafile

sed -e '/hrwang/H' -e '$G' datafile

#通過上面兩條命令,你會發現g把暫存緩衝區中的內容替換掉了模式空間中當前行的內容,此處即替換了最後一行。而G命令則把暫存緩衝區的內容追加到了模式空間的當前行後。此處即追加到了末尾。