| Sed﹝stream editor﹞也是以列為單位來處理文字,但是它不能算是一種列編輯器;因為它是從 standard input﹝鍵盤﹞讀入文字。而它的輸出會送到 standard output﹝螢幕﹞。而且 sed 以列為單位處理字串,每列只處理一次。
因為 sed 能從 standard input 讀進資料,所以它也能接受其他程式的輸出。同樣地,sed 的輸出也可以當成其他程式的輸入。而 ed 或 vi 並不能從 standard input 讀入文字,也不能輸出文字到 standard output,所以它們沒有這個能力。
Sed 也能用來處理檔案,但是我不想介紹。要處理檔案,用 vi 或 ed 會更方便,沒必要自討苦吃。
在說明用法以前,還有一件事要提醒一下,sed 未必「認得」中文。所以讀者最好先測試一下正在使用的 sed,這可是非常容易出問題的。
下指令 sed function,表示執行 sed,並且對你所輸入的每列文字執行 function。這個格式是我唯一會說到的用法,當你下了這個指令,sed 會從鍵盤讀入文字,而且在你按下【 Enter 】後立刻對這一列文字執行 function。這裡的 function 決定了處理文字的方式,如果你不指定,那 sed 就什麼也不做。文字處理完,會立刻輸出到螢幕上。比如你下指令 sed s/pig/dog/,然後輸入文字 That man has a pig.,按下【 Enter 】後螢幕會出現這列文字:That man has a dog.。如果你要離開 sed,就按【 ctrl-D 】。
從上面的例子可以看到 function 是 vi 的 line mode 的指令。但是我的例子只會出現 s 和 d,其他的我不用。我說過了,我不會用 sed 處理檔案。當你使用 s 作搜尋或替換時,最好用單引號 ' 包起來,也就是命令變成 sed 'function',這樣可以為你省去許多麻煩。
指令 ls -l | sed d 將不會印出任何東西。 ls -l 會顯示你目前目錄下檔案的詳細狀況。這個結果本來是要輸出到螢幕上的,但是你用 | 把結果送入 sed d,所以 sed 會把每一列都刪除後在送到螢幕上,因為你指定的 function 是 d,也就是刪除。所以這個指令沒啥意義,只是用來示範一下 sed 如何從別的程式接受資料。
現在說一個有用的例子,試著下指令 ls -l | sed '/^d/d'。這個指令會把開頭為 d 的列刪除。跟在 sed 後面的 function 是 /^d/d,所以 sed 會在每一列的開頭尋找字元 d,如果找到了,就把這一列刪除。剩下的是開頭不是 d 的列,也就是不是目錄的檔案。
Sed 最大的用處大概就是代換了,所以在這裡舉幾個例子。假設你的程式輸出這段文字: 文字之間的空格是由 tab 所造成的。這份資料可能是從某個資料庫輸出,而你只想看到第一行和最後一行,這個時候下指令 資料來源程式 | sed 's/^I.*^I/^I/' 可以達到你的要求。其中 ^I 是 tab,你要先按【 Ctrl-V 】再按【 Tab 】。但是實際上你什麼也看不到,我這裡用 ^I 是為了方便說明。我相信你無法用眼睛分辨出空格和 tab。最後面沒有加 g(global) 是因為 sed 搜尋樣式的原則是越長越好。
如果你想要自己實驗的話,可以把上面的文字放到檔案中﹝記得要用 tab 取代空格﹞,然後用 cat 輸出。所以上面的指令就變成 cat 檔案 | sed 's/^I.*^I/^I/'。為了方便,下面的指令會從 sed 開始,前面的資料輸入就省略了。
如果你不希望看到第三行的話,那你可以下指令 sed 's/[0-9][0-9]*^I//2'。放在最尾巴的 2 告訴 sed 只對第二個找到的樣式作代換。所以雖然第二行也是我們尋找的樣式,卻不會被代換。你可以用正整數 n 告訴 sed 對第 n 個找到的樣式作代換。當然,這個用法和 g(global) 犯沖,兩個一起用的話會出問題。
最後一個例子,指令 sed '/HERESY/s/[0-9][0-9]*/xxx/g'。這個指令會把含有 HERESY 的那兩列的第二行和第三行的數字用 xxx 取代。這也算是一種加密,只不過沒人有辦法解密。如你所看到的,你可以要求 sed 先檢查一列中是否包含某個樣式,如果包含了,才執行後面的代換。
| BGS |
126 |
135 |
COMIC |
| BGS |
223 |
335 |
GAME |
| BGS |
891 |
234 |
VI |
| HERESY |
369 |
1234 |
HOMEPAGE |
| HERESY |
555 |
899 |
WORD |
|