Sed

歷史

sed是為命令列處理資料檔案而構建的早期Unix命令之一，首次出現在Version 7 Unix中 。它很自然地演變成為流行的grep命令的後繼。 最初的動機與grep（g/re/p）的替換類似，因此稱為「g/re/s」。 考慮到這樣的話還會出現針對每個命令的專用程式，例如g/re/d，McMahon編寫了一個通用的面向行的流編輯器，該編輯器後來成為了sed。 sed的語法，特別是把/用於模式匹配，把s///用於替換，起源於sed的前身ed（當時ed很常用） 而且正規表示式語法影響了其他一些語言，特別是ECMAScript和Perl。後來，更強大的語言AWK問世，這些工具相互補充，讓通過shell指令碼完成強大的文字處理成為可能。sed和AWK常被認為Perl的祖先和靈感來源，並且影響了Perl的語法和語意，尤其影響了匹配和替換運算子。
GNU sed添加了一些新功能，包括檔案的就地編輯 。Super-sed 是sed的擴充版本，包含與Perl相容的正規表示式。sed的另一變體minised ，最初埃里克·雷蒙把4.1BSD sed通過逆向工程寫成，目前由René Rebe維護。在GNU計劃基於新的GNU正規表示式庫編寫了新版本的sed之前，GNU計劃一直使用minised。目前minised包含一些BSD sed的擴充，但不像GNU sed那樣功能豐富。它的優點是速度快，占用的記憶體少。它用於嵌入式系統，是Minix提供的sed版本。

工作模式

sed是一個面向行的文字處理實用程式：它從輸入流或檔案中逐行讀取文字到一個稱為模式空間 的內部緩衝區。每讀一行開始一個迴圈  。對於模式空間，sed會應用sed指令碼 指定的一個或多個操作。sed實現了一種程式語言，其中包含大約25個指定文字操作的命令  。對於每個輸入行，在執行指令碼之後，sed通常輸出模式空間（由指令碼修改的行），然後從下一行再次開始迴圈。其他指令碼結束行為可通過sed選項和指令碼命令獲得，例如d刪除模式空間，q退出，N立即將下一行添加到模式空間，等等。因此，sed指令碼對應於迴圈體，迴圈體遍歷流的行，其中迴圈本身和迴圈變數（目前行號）是隱式的並由sed維護。
可以在命令列上指定sed指令碼（ -e選項），也可以從單獨的檔案中讀取（ -f選項）。sed指令碼中的命令可以採用行號或正規表示式的作為位址  。該位址確定決定命令何時執行。例如，2d將僅在第二個輸入行上執行d（刪除）命令（列印除第二個輸入行之外的所有行），而/^ /d將刪除以空格開頭的所有行。一些單獨的特殊緩衝區，即保持空間，可以由幾個sed命令使用，用於在迴圈之間保持和累積文字。sed的命令語言只有兩個變數（「保持空間」和「模式空間」）和類似GOTO的分支功能；然而，這種語言是圖靈完備的， 用深奧sed指令碼甚至寫得出推箱子、打磚塊、西洋棋和俄羅斯方塊等遊戲。 
為輸入流的每一行執行一次主迴圈，在輸入的每一行上計算sed指令碼。sed指令碼的每一行都是模式-動作對，指示著要匹配的模式和要執行的操作，可以將其重新組合為條件語句。因為主迴圈、工作變數（模式空間和保持空間）、輸入和輸出流以及預設操作（複製行到模式空間、列印模式空間）是隱式的，所以可以編寫簡潔的單行程式。例如，以下sed程式：
10q
將列印輸入的前10行，然後停止。

替換命令

下面的範例顯示了sed用於替換的典型（也是最常見的）用法。這種用法確實是sed的最初動機：
sed 's/regexp/replacement/g' inputFileName > outputFileName
在某些版本的sed中，表達式的前面必須加上-e，以表示後面跟著一個表達式。s表示替換，而g表示全域，這意味著行中的所有匹配項都將被替換。要搜尋的正規表示式（即pattern）放在第一個分隔符號（此處為斜槓）之後，而要替換成的字串跟在第二個分隔符號後面。斜槓（/）是傳統的符號，起源於ed中的「搜尋」字元，但其實在pattern和替換文字中都未出現的任何其他符號都可以用作分隔符號，使其可讀性更強；這有助於避免「傾斜牙籤綜合徵」。
替換命令源自ed中的搜尋-替換，實現了簡單的解析和模板化 。regexp提供模式匹配和通過子表達式儲存文字的功能，而replacement可以是純文字，也可以是包含「完全匹配」&，或第n 個子表達式（從\1到\9）這種特殊跳脫序列的格式字串。例如， sed -r "s/(cat|dog)s?/\1s/g"用「cat」或「dog"替換所有出現的「cats」或「dogs」，而不複製現有的「s」：在正規表示式中，(cat|dog)是第一個（也是唯一）儲存的子表達式，格式字串中的\1將其替換到輸出里。

sed用作過濾器

在Unix下，sed通常用作管道中的過濾器：
generateData | sed 's/x/y/g'
也就是說，諸如「generateData」之類的程式生成資料，然後用sed把x替換成y。例如：
$ echo xyz xyz | sed 's/x/y/g'yyz yyz

基於檔案的sed指令碼

將幾個sed命令（每行一個命令）放入指令碼檔案（例如subst.sed）中然後使用-f選項從檔案中執行命令（例如s/x/y/g）通常很有用：
sed -f subst.sed inputFileName > outputFileName
可以在指令碼檔案中放置任意數量的命令，使用指令碼檔案也可以避免shell跳脫或替換的問題。
這樣的指令碼檔案可以直接從命令列執行，方法是在其前面加上一個包含sed命令的"shebang行"，並為該檔案分配可執行權限。例如，可以使用以下內容建立檔案subst.sed：
!/bin/sed -f
s/x/y/g

然後，目前用戶可以使用chmod命令使檔案可執行：
chmod u+x subst.sed
然後可以直接從命令列執行該檔案：
subst.sed inputFileName > outputFileName

就地編輯

GNU sed中引入的-i選項允許就地編輯檔案（實際上，在後台建立了一個臨時輸出檔案，然後將原始檔案替換為臨時檔案）。例如：
sed -i 's/abc/def/' fileName

其他簡單的例子

下面是各種sed指令碼；可以把它們作為參數傳遞給sed，或者放入一個單獨的檔案並通過-f執行或通過使指令碼本身可執行來執行。
要把檔案中某個單詞（例如IRC密碼）替換為「REDACTED」，並儲存結果：
sed -i s/yourpassword/REDACTED/ ./status.freenode.log
要刪除包含「yourword」一詞的所有行（ 位址 為「/yourword/」）：
/yourword/ d
要刪除所有「yourword」這個詞：
s/yourword//g
要同時從檔案中刪除兩個單詞：
s/firstword//g
s/secondword//g
為了在一行表示前面的範例，比如在命令列輸入時，可以通過分號連接兩個命令：
sed "s/firstword//g; s/secondword//g" inputFileName

限制和替代方案

雖然sed具有簡單性和局限性，但對於大量用途而言，它的功能已經足夠強大。對於更複雜的處理，可以使用更強大的語言，如AWK或Perl 。雖然使用保持緩衝區理論上可以進行任意複雜的轉換，但如果轉換行的方式比正規表示式提取和模板替換更複雜，則使用一般會使用上面提到的更強大的語言。
相反，對於更簡單的操作，grep （列印匹配模式的行），head（列印檔案的第一部分），tail（列印檔案的最後部分）和tr（翻譯或刪除字元）等專門的Unix實用程式通常更可取。對於設計用於執行的特定任務，此類專用實用程式通常比較一般的解決方案（如sed）更簡單、清晰和快速。
ed/sed命令和語法繼續用於衍生程式，例如文字編輯器vi和vim。sam/ssam與ed/sed類似，其中sam是Plan 9編輯器，ssam是它的流介面，其功能類似於sed。