【shell】sed


sed是一個非交互性性文本編輯器, 它編輯文件或標准輸入導出的文件拷貝。標准輸入可能是來自鍵盤、文件重定向、字符串或變量,或者是一個管道文件。sed可以隨意編輯小或大的文件,有許多 sed命令用來編輯、刪除,並允許做這項工作時不在現場。sed一次性處理所有改變,因而變得很有效,對用戶來說,最重要的是節省了時間。sed必須通過行號和正則表達式指定要改變的文本行

sed怎樣讀取數據:
    sed從文件的一個文本行或從標准輸入的幾種格式中讀取數據,將之拷貝到一個編輯緩沖區,然后讀命令行或腳本的第一條命令,並使用這些命令查找模式或定位行號編輯它,重復過程直到命令結束

sed命令的調用:
    在命令行鍵入命令;將sed命令插入腳本文件,然后調用sed;將sed命令插入腳本文件,並使sed腳本可執行
    sed [option] sed命令輸入文件            在命令行使用sed命令,實際命令要加單引號
    sed [option] -f sed腳本文件 輸入文件     使用sed腳本文件
    sed腳本文件 [option] 輸入文件            第一行具有sed命令解釋器的sed腳本文件
    option如下:
      n 不打印; sed不寫編輯行到標准輸出,缺省為打印所有行(編輯和未編輯),p命令可以用來打印編輯行
      c 下一命令是編輯命令,使用多項編輯時加入此選項
      f 如果正在調用sed腳本文件,使用此選項,此選項通知sed一個腳本文件支持所用的sed命令,如
          sed -f myscript.sed input_file  這里myscript.sed即為支持sed命令的文件
    使用重定向文件即可保存sed的輸出

使用sed在文本中定位文本的方式:
    x       x為一行號,比如1
    x,y     表示行號范圍從x到y,如2,5表示從第2行到第5行
    /pattern/    查詢包含模式的行,如/disk/或/[a-z]/
    /pattern/pattern/   查詢包含兩個模式的行,如/disk/disks/
    /pattern/,x  在給定行號上查詢包含模式的行,如/disk/,3
    x,/pattern/  通過行號和模式查詢匹配行,如 3,/disk/
    x,y!    查詢不包含指定行號x和y的行

基本sed編輯命令:
    p      打印匹配行                      c/    用新文本替換定位文本
    =      顯示文件行號                    s     使用替換模式替換相應模式
    a/     在定位行號后附加新文本信息        r     從另一個文本中讀文本
    i/     在定位行號后插入新文本信息        w     寫文本到一個文件
    d      刪除定位行                      q     第一個模式匹配完成后退出或立即退出
    l      顯示與八進制ASCII代碼等價的控制字符        y  傳送字符
    n      從另一個文本中讀文本下一行,並附加在下一行   {}     在定位行執行的命令組
    g      將模式2粘貼到/pattern n/

基本sed編程舉例:
    使用p(rint)顯示行: sed -n '2p' temp.txt   只顯示第2行,使用選項n
    打印范圍:  sed -n '1,3p' temp.txt         打印第1行到第3行
    打印模式:  sed -n '/movie/'p temp.txt     打印含movie的行
    使用模式和行號查詢:  sed -n '3,/movie/'p temp.txt   只在第3行查找movie並打印
    顯示整個文件:  sed -n '1,$'p temp.txt      $為最后一行
    任意字符:  sed -n '/.*ing/'p temp.txt     注意是.*ing,而不是*ing
    打印行號:  sed -e '/music/=' temp.txt
    附加文本:(創建sed腳本文件)chmod u+x script.sed,運行時./script.sed temp.txt
        #!/bin/sed -f
        /name1/ a/             #a/表示此處換行添加文本
        HERE ADD NEW LINE.     #添加的文本內容
    插入文本: /name1/ a/ 改成 4 i/ 4表示行號,i插入
    修改文本: /name1/ a/ 改成 /name1/ c/ 將修改整行,c修改
    刪除文本: sed '1d' temp.txt  或者 sed '1,4d' temp.txt
    替換文本: sed 's/source/OKSTR/' temp.txt     將source替換成OKSTR
             sed 's//$//g' temp.txt             將文本中所有的$符號全部刪除
             sed 's/source/OKSTR/w temp2.txt' temp.txt 將替換后的記錄寫入文件temp2.txt
    替換修改字符串: sed 's/source/"ADD BEFORE" &/p' temp.txt
             結果將在source字符串前面加上"ADD BEFORE",這里的&表示找到的source字符並保存
    sed結果寫入到文件: sed '1,2 w temp2.txt' temp.txt
                     sed '/name/ w temp2.txt' temp.txt
    從文件中讀文本: sed '/name/r temp2.txt' temp.txt
    在每列最后加文本: sed 's/[0-9]*/& Pass/g' temp.txt
    從shell向sed傳值: echo $NAME | sed "s/go/$REP/g"   注意需要使用雙引號

快速一行命令:
    's//.$//g'         刪除以句點結尾行
    '-e /abcd/d'       刪除包含abcd的行
    's/[][][]*/[]/g'   刪除一個以上空格,用一個空格代替
    's/^[][]*//g'      刪除行首空格
    's//.[][]*/[]/g'   刪除句號后跟兩個或更多的空格,用一個空格代替
    '/^$/d'            刪除空行
    's/^.//g'          刪除第一個字符,區別  's//.//g'刪除所有的句點
    's/COL/(.../)//g'  刪除緊跟COL的后三個字母
    's/^////g'         刪除路徑中第一個/

///////////////////////////////////////////////////////////////////////

1、使用句點匹配單字符    句點“.”可以匹配任意單字符。“.”可以匹配字符串頭,也可以是中間任意字符。假定正在過濾一個文本文件,對於一個有1 0個字符的腳本集,要求前4個字符之后為X C,匹配操作如下:. . . .X C. . . .
2、在行首以^匹配字符串或字符序列    ^只允許在一行的開始匹配字符或單詞。在行首第4個字符為1,匹配操作表示為:^ . . . 1
3、在行尾以$匹配字符串或字符    可以說$與^正相反,它在行尾匹配字符串或字符, $符號放在匹配單詞后。如果在行尾匹配單詞j e t 0 1,操作如下:j e t 0 1 $    如果只返回包含一個字符的行,操作如下:^ . $
4、使用*匹配字符串中的單字符或其重復序列    使用此特殊字符匹配任意字符或字符串的重復多次表達式。
5、使用/屏蔽一個特殊字符的含義    有時需要查找一些字符或字符串,而它們包含了系統指定為特殊字符的一個字符。如果要在正則表達式中匹配以* . p a s結尾的所有文件,可做如下操作:/ * / . p a s
6、使用[]匹配一個范圍或集合     使用[ ]匹配特定字符串或字符串集,可以用逗號將括弧內要匹配的不同字符串分開,但並不強制要求這樣做(一些系統提倡在復雜的表達式中使用逗號),這樣做可以增加模式的可讀性。使用“ -”表示一個字符串范圍,表明字符串范圍從“ -”左邊字符開始,到“ -”右邊字符結束。假定要匹配任意一個數字,可以使用:[ 0 1 2 3 4 5 6 7 8 9 ]    要匹配任意字母,則使用:[ A - Z a - z ]表明從A - Z、a - z的字母范圍。
7、使用/{/}匹配模式結果出現的次數    使用*可匹配所有匹配結果任意次,但如果只要指定次數,就應使用/ { / },此模式有三種形式,即:
    pattern/{n/} 匹配模式出現n次。
    pattern/{n,/} 匹配模式出現最少n次。
    pattern/{n,m} 匹配模式出現n到m次之間,n , m為0 - 2 5 5中任意整數。
    匹配字母A出現兩次,並以B結尾,操作如下:A / { 2 / } B匹配值為A A B    匹配A至少4次,使用:A / { 4 , / } B

 

例如:修改匹配的第N個內容

文本:
aa
88
bb
88
88
cc
88
88

替換第一個88為--:
1 sed '0,/88/s//--/' file
2 sed ':a;N;$!ba;s/88/--/' file
[解析]
這有兩種方法,第一個是只匹配到第一個88為止,然后替換那個88為--。
第二個句子是通過循環把文本全部讀進pattern space 然后只替換第一個。

替換第N[3]個88為--:
1 sed '/88/{x;s/^/./;/^\.\{3\}$/{x;s/.*/--/;x};x;}' file
2 sed ':a;N;$!ba;s/88/--/3' file
[解析]
第一個命令叫打點記數法,因為sed沒有 var++ 之類的操作來記數。
第二個命令和上面第一個其實是一樣的原理,全部讀入文本后統一替換第3個匹配的內容。

替換最后一個匹配的88為--:
1 sed ':a;/\n88/!{$s/88/--/;N;ba};P;D' file
2 sed ':a;N;$!ba;s/\(.*\)88/\1--/' file
[解析]
第一個命令,沒匹配到 /\n88/ 的內容就讀取下一行,然后 ba 跳轉去開始處,如果讀取到88的行呢,就執行后面的 P;D 組合,D也有循環功能,一直把匹配 \n88 內容的第一行打印,刪除,直到不匹配/\n88/(因為換行符已經被打印出去了,所以不再會匹配到 \n88),這時候才繼續往下讀,如果又讀到88的行,那么又執行P;D循環,同上操作。一直到匹配到最后一個88的行,繼續讀取到末行時執行替換,N 因為沒有下一行可讀,所以會自動中止命令,因為沒有 -n 參數會打印 pattern space 里的內容到屏幕,所以就不會再執行后面的 ba 避免了死循環,這樣的用法只存在於 GNU sed ,大家注意。所以這整個流程只會替換最后一個88。
第二個命令其實和上面的都一樣,也是全部讀進 pattern space 里,最后利用正則的貪婪替換掉最后一個88。







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM