這篇記錄一下sed的基本用法,建議看下sed與awk第三版裡面介紹的很詳細,sed通過Regex匹配出命令處理文本,如果對正則不熟悉是件很頭疼的事。注意以下指令碼都是在指令檔上測試的使用命令sed -f scrift files
1.sed先讀取一行至模式空間,取前先清除以前模式空間內容(多行模式下讀取命令N除外),指令碼從指令碼頂部開始處理模式空間的內容,處理一條命令更新模式空間內容,新的命令在更新後的模式空間上進行,到達指令碼底部後預設送往螢幕顯示也可以使用-n禁止這個預設輸出,sed 對源檔案內容不做修改。
2.sed命令可以指定0個1個或2個地址,每個地址是一個描述模式,行號或行定址符號的Regex。
3.sed命令 格式sed [options] 'command' files; sed [options] -f scriptfile files
3.1 追加,插入,更改
a\ 在當前行後面加入一行文本。 i\ 在當前行上面插入資料,新插入的資料不會被讀入處理。 c\ 改變行的文本,如1~3行變成123456789 1,3c\123456789 $a\end of file 在最後一行後加入 $i\end of file 在最後一行前加入 $c\end of file 替換掉最後一行 這裡碰到奇怪的問題,sed與awk第三版說aic會修改模式空間的內容,內建協助檔案沒提及,測試發現aic命令執行後後面的命令沒被執行,如 1{ c\1234 = = p p p } 更改第一行內容為1234,後面列印行號和測試的輸出,但結果後面的命令不執行了,如果知道請告知一下謝謝。
3.2 替換 [address]s/pattern/replacement/flags 用replacement替換Regexpattern。flag可以是一下標示。
n 1~512之間的數字,表示只替換第n次出現的pattern g 全部替換,沒有g只替換第一次出現的pattern p 只是列印 W file 寫入檔案 如果沒有匹配地址那麼匹配全部行,和地址不同地址的定界符為斜杠/,Regex可以使用任一字元分割如s/444/111/,可以寫成 s244421112,現在分割符號是2,當然這是例子最好不要這樣寫。如果運算式內包含定界符那麼需要用反斜線來轉義它。 在pattern部分我們可以用\(和\)來分塊,在替換部分repalcement可以使用\n(n是數字)來表示pattern的第幾塊,使用&表示整個pattern匹配出來的字串, 例子如文檔中多處出現google裡面的o是不定的,但發現少寫了個e。可以 s/\<go\{2,\}gl\>/&e/g,\<和\>是錨定單詞,&e表示只在原來基礎上加個e。 例子如google內o不定發現少了個g,替換時要保留原來o的個數怎麼辦呢?這就需要用塊了,s/\<g\(o\{2,\}\)le\>/g\1gle/g,這裡pattern內用\(和\)分了塊,然後在replacement內調用塊內的內容\1。
3.3 刪除行d,如刪除1,3行 1,3d
3.4 列表l 列出不能列印字元的清單,將不能列印的字元顯示為兩個數字顯示的ascii代碼,如\n \t...
3.5 轉換 [address]y/abc/xyz/
這個命令按位置將字串abc中的每個字元轉換為xyz中對應的字元。
如轉換大小寫可以y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
3.6 列印 p
3.7 列印行號 =
3.8 讀入下一行 n 用下一命令處理,而不是重新處理,如下找到行111的行處理後,下一行如果是空行那麼刪除下一行
/111/{ s/111/222/; n; /^$/d; } 實際上,next命令導致輸入的下一行取代模式空間的當前行,指令碼的後續命令作用於替換後的行。
3.9 讀寫檔案
r file 讀入檔案不存在也不會報錯 w file 寫入檔案如果不存在將建立一個,如果存在那麼首次寫入清空舊資料,以後寫入為追加寫入。
3.10 退出 q 退出sed
如匹配到111的行後退出 sed /111/q file
3.11 ! 表示後面的命令對所有沒有被選定的行發生作用。
3.12 = 列印當前行
3.13 # 注釋行
進階命令,sed通常讀一行至模式空間,並逐條執行指令碼中的命令,指令碼結束時輸出這一行並清空模式空間,然後讀下一行至模式空間如此迴圈,sed的多行模式命令可以一次讀入多行然後進行匹配處理,如處理跨行的片語。
3.14 多行模式空間 N D P 對應單行模式下的n d p
P只列印多行模式的第一行,p列印整個模式控制項內容。P經常出現在N之後和D之前。 D只刪除多行模式的第一行,不讀新入行至模式空間,但會回到指令碼頂端,重執行指令碼,d 刪除模式空間的內容,導致讀入新行並重新執行指令碼 N讀取新的行並添加只模式空間現有內容後,讀入的行自動用換行\n分割開來。讀入多行模式空間內的所有行可以看成是帶有換行\n的單行資料,^匹配第一行的開頭$匹配最後一行的結尾。例如替換跨行的片語hello sed,替換成單行。 ex1:替換相鄰行 hello sed 替換成一行 hello sed /hello$/{ N; s/hello\nsed/hello sed/ } ex2: 將多個空白行替換成一個空白行/^ *$/{ N; /^ *\n$/D;} 如果把D改成小寫d,那麼當空白行為偶數時全部空白被刪除,奇數時保留1行,因為模式空間湊夠兩行後d命令刪除空間內的全部並取下一行,使用D先匹配到一行空白行,取下一條如果是連續空白行那麼刪除第一行後,會回到指令碼頂端,重新按當前模式空間的內容執行指令碼。
3.15 採用保持空間來儲存模式空間內容,使用H h G g x操作保持空間的內容
模式空間是當前處理的緩衝區,還有個個保持空間,類似剪下板,可以將處理的內容複寫到保持空間, hold h/H 將模式空間的內容複寫/追加至保持空間 get g/G 將保持空間的內容賦值/追加至模式空間 x 模式空間和保持空間的內容互換 h 拷貝選中內容到保持空間,以前緩衝的內容被清掉。 H 追加選中內容到保持空間,以前緩衝的內容不變,這樣可以緩衝多行。 g 擷取保持空間內容,並 替換 模式空間中的內容。 G 擷取保持空間內容,並 追加 模式空間的 後面。
3.16 使用分支和條件指令 : b t T
分支(b)和測試(T/t)命令指令碼中的控制轉移到包含特殊標籤的行。如果沒有標籤那麼轉移到指令碼結尾處。 分支b用於無條件轉移 [address] b [label] label可選,當無label時跳至指令碼結尾。 測試t用於條件轉移 [address] t [label] label可選,當無label時跳至指令碼結尾。如果當前匹配地址的行上進行了成功的替換,那麼test命令會轉到標 簽處 測試(T)和(t)相反 用於條件轉移 [address] t [label] label可選,如果當前匹配地址的行上進行了替換失敗,那麼test命令會轉到標籤處 T 和 t測試的是s///替換命令的結果 標籤本身佔有一行使用:開頭,使用b label無條件跳轉,使用分支b跳轉方式刪除多行空白,替換成一行空白,當讀到空白行時迴圈讀出,然後將多行模式空間的空白行替換成單一空白行/^ *$/{:rdn N; /^\( *\n*\)\{1,\}$/b rdn; s/^\( *\n*\)\{1,\}\n/\n/}使用測試t跳轉方式刪除多行空白,替換成一行空白,當讀到空白行時,讀下一行然後替換兩空白行為一空白行,如替換成功接著讀下一行,直到替換失敗/^ *$/{:loop N; s/^\( *\n*\)\{1,\}$//; t loop}
4.[options]
4.1 -e command, --expression=command 允許多台編輯。 4.2 -h, --help 列印協助,並顯示bug列表的地址。 4.3 -n, --quiet, --silent 取消預設輸出。 4.4 -f, --filer=script-file 引導sed指令檔名。 4.5 -V, --version 列印版本和著作權資訊。
5.元字元集
^ 錨定行的開始 如匹配1111開頭的行,/^1111/ $ 錨定行的結束 如匹配aaaa結尾的行,/aaaa$/ . 匹配一個字元 包括分行符號號 * 匹配零或多個字元 [] 匹配 一個 指定範圍的字元 如[123]k匹配1k 2k 3k [^]匹配一個不在指定範圍內的字元 \(..\) 儲存匹配的字元,如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的行。 \+ 至少一個匹配 \? 0個或1個 \| `REGEXP1\|REGEXP2' Matches either REGEXP1 or REGEXP2. 如刪除包含111或222的行/111\|222/d
6.嵌套分組命令
sed使用大括弧將一個地址嵌套在另一個地址中,或相同地址應用多個命令,例如匹配3~8行內匹配包含444的地址sed指令檔可以如下3,8{ /444/{ s/444/333/ 其他指令 }} 上面例子s/444/333/前又可以加匹配地址,每個命令可以有自己的地址並允許多層嵌套,如果命令之間有個分號,那麼可以多個sed命令放同一行,有些命令會把;當輸出資料了,如a,未閱讀方便不提倡寫在同一行。一些sed說明注釋智能在第一行出現,命令內不能有多餘空格,大括弧後不能有空格,右大括弧要單獨一行的約束,但是再我使用的sed版本GNU sed 版本 4.2.1並沒有這些限制。