Sed﹝stream editor﹞也是以列為單位來處理文字, 但是它不能算是一種列編輯器;因為它是從 standard input﹝鍵盤﹞讀入文字。 而它的輸出會送到 standard output﹝螢幕﹞。 而且 sed 以列為單位處理字串,每列只處理一次。因為 sed 能從 standard input 讀進資料,所以它也能接受其他程式的輸出。 同樣地,sed 的輸出也可以當成其他程式的輸入。 而 ed 或 vi 並不能從 standard input 讀入文字, 也不能輸出文字到 standard output,所以它們沒有這個能力。 如果你看不懂這一段, 最好看一下 UNIX 文字工具: 導管。
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 搜尋樣式的原則是越長越好。
BGS 126 135 COMIC BGS 223 335 GAME BGS 891 234 VI HERESY 369 1234 HOMEPAGE HERESY 555 899 WORD 如果你想要自己實驗的話,可以把上面的文字放到檔案中﹝記得要用 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 先檢查一列中是否包含某個樣式, 如果包含了,才執行後面的代換。
製作人、 修改記錄 |
李易霖 (02/8/19) --- |