sed簡介
sed 是一種線上編輯器,它一次處理一行内容。處理時,把目前處理的行存儲在臨時緩沖區中,稱為“模式空間”(pattern space),接着用sed指令處理緩沖區中的内容,處理完成後,把緩沖區的内容送往螢幕。接着處理下一行,這樣不斷重複,直到檔案末尾。檔案内容并沒有改變,除非你使用重定向存儲輸出。sed主要用來自動編輯一個或多個檔案;簡化對檔案的反複操作;編寫轉換程式等。

可以通過定址來定位你所希望編輯的行,該位址用數字構成,用逗号分隔的兩個行數表示以這兩行為起止的行的範圍(包括行數表示的那兩行)。如1,3表示1,2,3行,美元符号($)表示最後一行。範圍可以通過資料,正規表達式或者二者結合的方式确定 。
調用sed指令有兩種形式:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
選項
-e command, --expression=command允許多台編輯
$ sed -e '1,5d' -e 's/test/check/' example #(-e)選項允許在同一行裡執行多條指令。如例子所示,第一條指令删除1至5行,第二條指令用check替換test。指令的執行順序對結果有影響。如果兩個指令都是替換指令,那麼第一個替換指令将影響第二個替換指令的結果。
$ sed --expression='s/test/check/' --expression='/love/d' example #一個比-e更好的指令是--expression。它能給sed表達式指派。
-h, --help
列印幫助,并顯示bug清單的位址。
-n, --quiet, --silent
不列印; sed不寫編輯行到标準輸出,預設為列印所有行(編輯和未編輯),p指令可以用來列印編輯行
-f, --filer=script-file
引導sed腳本檔案名。
-v, --version
列印版本和版權資訊。
5. 元字元集
^
錨定行的開始 如:/^sed/比對所有以sed開頭的行。
$
錨定行的結束 如:/sed$/比對所有以sed結尾的行。
.
比對一個非換行符的字元 如:/s.d/比對s後接一個任意字元,然後是d。
*
比對零或多個字元 如:/*sed/比對所有模闆是一個或多個空格後緊跟sed的行。
[]
比對一個指定範圍内的字元,如/[ss]ed/比對sed和sed。
[^]
比對一個不在指定範圍内的字元,如:/[^a-rt-z]ed/比對不包含a-r和t-z的一個字母開頭,緊跟ed的行。
\(..\)
儲存比對的字元,如s/\(love\)able/\1rs,loveable被替換成lovers。
&
儲存搜尋字元用來替換其他字元,如s/love/**&**/,love這成**love**。
\<
錨定單詞的開始,如:/\<love/比對包含以love開頭的單詞的行。
\>
錨定單詞的結束,如/love\>/比對包含以love結尾的單詞的行。
x\{m\}
重複字元x,m次,如:/0\{5\}/比對包含5個o的行。
x\{m,\}
重複字元x,至少m次,如:/o\{5,\}/比對至少有5個o的行。
x\{m,n\}
重複字元x,至少m次,不多于n次,如:/o\{5,10\}/比對5--10個o的行。
標明行的範圍:逗号
$ sed -n '/test/,/check/p' example #所有在模闆test和check所确定的範圍内的行都被列印。
$ sed -n '5,/^test/p' example #列印從第五行開始到第一個包含以test開始的行之間的所有行。
$ sed '/test/,/check/s/$/sed test/' example #對于模闆test和west之間的行,每行的末尾用字元串sed test替換。
替換标記
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指令的分隔符一樣,斜線可以被替換成其它的字元。
$ sed '1,10y/abcde/abcde/' example #把1--10行内所有abcde轉變為大寫,注意,正規表達式元字元不能使用這個指令。
q:退出sed
$ sed '10q' example #列印完第10行後,退出sed。
d:從模闆塊(pattern space)位置删除行。
$ sed '2d' example #删除example檔案的第二行。
$ sed '2,$d' example #删除example檔案的第二行到末尾所有行。
$ sed '$d' example #删除example檔案的最後一行。
$ sed '/test/'d example #删除example檔案所有包含test的行。
r file:從file中讀行。
$ sed '/test/r file' example #file裡的内容被讀進來,顯示在與test比對的行後面,如果比對多行,則file的内容将顯示在所有比對行的下面。
s:用知道那個模式替換目前模式。s/re/string,用string替換正規表達式re。
$ sed 's/test/mytest/g' example #在整行範圍内把test替換為mytest。如果沒有g标記,則隻有每行第一個比對的test被替換成mytest。
$ sed -n 's/^test/mytest/p' example #(-n)選項和p标志一起使用表示隻列印那些發生替換的行。也就是說,如果某一行開頭的test被替換成mytest,就列印它。
$ sed 's/^192.168.0.1/&localhost/' example #&符号表示替換換字元串中被找到的部份。所有以192.168.0.1開頭的行都會被替換成它自已加 localhost,變成192.168.0.1localhost。
$ sed -n 's/\(love\)able/\1rs/p' example #love被标記為1,所有loveable會被替換成lovers,而且替換的行會被列印出來。
$ sed 's#10#100#g' example #不論什麼字元,緊跟着s指令的都被認為是新的分隔符,是以,“#”在這裡是分隔符,代替了預設的“/”分隔符。表示把所有10替換成100。
=:列印目前行号碼。
$ sed '/a/=' mm
1
a
b
c
$ sed -n '/a/=' mm
引用shell變量
在sed的指令行中引用shell變量時要使用雙引号,而不是通常所用的單引号。下面是一個根據name變量的内容來删除named.conf檔案中zone段的腳本:
name='zone\ "localhost"'
sed "/$name/,/};/d" named.conf
sed腳本
sed腳本是一個sed的指令清單,啟動sed時以-f選項引導腳本檔案名。sed對于腳本中輸入的指令非常挑剔,在指令的末尾不能有任何空白或文本,如果在一行中有多個指令,要用分号分隔。以#開頭的行為注釋行,且不能跨行。
sed進階指令(g、h、g、h、n、n、x)
由于各種各樣的原因,比如使用者希望在某個條件下腳本中的某個指令被執行,或者希望模式空間得到保留以便下一次的處理,都有可能使得sed在處理檔案的時候不按照正常的流程來進行。這個時候,sed設定了一些進階指令來滿足使用者的要求。
+ g:[address[,address]]g 将hold space中的内容拷貝到pattern space中,原來pattern space裡的内容清除
+ g:[address[,address]]g 将hold space中的内容append到pattern space\n後
+ h:[address[,address]]h 将pattern space中的内容拷貝到hold space中,原來的hold space裡的内容被清除
+ h:[address[,address]]h 将pattern space中的内容append到hold space\n後
+ d:[address[,address]]d 删除pattern中的所有行,并讀入下一新行到pattern中
+ d:[address[,address]]d 删除multiline pattern中的第一行,不讀入下一行
pattern space相當于工廠中的房間sed把流内容在這裡處理。
hold space相當于倉庫,加工的半成品在這裡臨時儲存。
你可以将pattern space看成是一個流水線,所有的動作都是在“流水線”上執行的;而hold space是一個“倉庫”,“流水線”上的東東都可以放到這裡。
不論是使用g、g還是h、h,它們都是将hold space裡面的内容“copy”到pattern space中或者将pattern space中的内容“copy”到hold space中。
英文解釋如下
the "h" command copies the pattern buffer into the hold buffer. the pattern buffer is unchanged.
instead of exchanging the hold space with the pattern space, you can copy the hold space to the pattern space with the "g" command. this deletes the pattern space. if you want to append to the pattern space, use the "g" command. this adds a new line to the pattern space, and copies the hold space after the new line.
示例:用sed模拟出tac的功能(倒序輸出)。
檔案内容
$cat mm
2
3
解決方法:
$sed ‘1!g;h;$!d’mm
1!g第1行不 執行“g”指令,從第2行開始執行。$!d,最後一行不删除(保留最後1行)
圖解分析過程
p:pattern space;h:hold space;藍色:hold space中的資料;綠色:pattern space中的資料
x表示互換模闆塊中的文本和緩沖區中的文本。
$ sed -e '/test/h' -e '/check/x' example #互換模式空間和保持緩沖區的内容。也就是把包含test與check的行互換。
保持和擷取:h指令和g指令
$ sed -e '/test/h' -e '$g example #在這個例子裡,比對test的行被找到後,将存入模式空間,h指令将其複制并存入一個稱為保持緩存區的特殊緩沖區内。第二條語句的意思是,當到達最後一行後,g指令取出保持緩沖區的行,然後把它放回模式空間中,且追加到現在已經存在于模式空間中的行的末尾。在這個例子中就是追加到最後一行。簡單來說,任何包含test的行都被複制并追加到該檔案的末尾。
行轉列的一個例子
ls -1 | sed -ne "h;$ {x;s/\n/ /g;p}"
h表示把pattern space 的内容追加到hold space中去,h可以帶一個位址,這裡用的是$,表示到檔案的末尾,然後用x将之取到pattern space中,把\n替換成空格再列印即可。
n指令
n指令簡單來說就是提前讀取下一行,覆寫模型空間前一行(并沒有删除,是以依然列印至标準輸出),如果指令未執行成功(并非跳過:前端條件不比對),則放棄之後的任何指令,并對新讀取的内容,重頭執行。
列印偶數行
$cat aaa
this is 1
this is 2
this is 3
this is 4
this is 5
$sed -n 'n;p' aaa //-n表示隐藏預設輸出内容
this is 4
注釋:讀取this is 1,執行n指令,此時模式空間為this is 2,執行p,列印模式空間内容this is 2,之後讀取this is 3,執行n指令,此時模式空間為this is 4,執行p,列印模式空間内容this is 4,之後讀取this is 5,執行n指令,因為沒有了,是以退出,并放棄p指令。
$ sed '/test/{ n; s/aa/bb/; }' example #如果test被比對,則移動到比對行的下一行,替換這一行的aa,變為bb,并列印該行,然後繼續。
n指令簡單來說就是追加下一行到模式空間,同時将兩行看做一行,但是兩行之間依然含有\n換行符,如果指令未執行成功(并非跳過:前端條件不比對),則放棄之後任何指令,并對新讀取的内容,重頭執行sed。sed并不對每行末尾\n進行處理,但是對n指令追加的行間\n進行處理,因為此時sed将兩行看做一行。
列印奇數行
sed -n '$!n;p' aaa
this is 1
this is 3
this is 5
!:表示後面的指令對所有沒有被標明的行發生作用。
注釋:讀取1,$!條件滿足(不是尾行),執行n指令,得出1\n2,執行p,列印得1,讀取3,$!條件滿足(不是尾行),執行n指令,得出3\n4,執行p,列印得3,讀取5,$!條件不滿足,跳過n,執行p,列印得5
d指令
d指令是删除目前模式空間開端至\n的内容(不在傳至标準輸出),放棄之後的指令,對剩餘模式空間重新執行sed。
從aaa檔案中讀取最後一行
sed 'n;d' aaa
注釋:讀取1,執行n,得出1\n2,執行d,得出2,執行n,得出2\n3,執行d,得出3,依此類推,得出5,執行n,條件失敗退出,因無-n參數,故輸出5
參考至:http://blog.csai.cn/user1/21439/archives/2007/19536.html
http://hi.baidu.com/aaa103439/item/dbaa6d0d27b4f812cc34eab8
http://www.cnblogs.com/fhefh/archive/2011/11/22/2259097.html
http://febest15.blog.163.com/blog/static/544960062008329114610389/
http://www.cnblogs.com/franktan/archive/2010/03/23/1692831.html
http://blog.csdn.net/jeffreyst/article/details/8775991
本文原創,轉載請注明出處、作者
如有錯誤,歡迎指正
作者:czmmiao 文章出處:http://czmmiao.iteye.com/blog/1899880