sed入门

原出处:http://phi.sinica.edu.tw/aspac/reports/96/96005/index.html
1.Introduction
  Sed(Stream EDitor)為 UNIX 系統上提供將編輯工作自動化的編輯器 , 使用者無需直接編輯資料。使用者可利用 sed 所提供 20 多種不同的函數參數 , 組合(註解 [1])它們完成不同的編輯動作。此外 , 由於 sed 都以行為單位編輯文件 , 故其亦是行編輯器(line editor)。

 一般 sed 最常用在編輯那些需要不斷重覆某些編輯動作的文件上 , 例如將文件中的某個字串替換成另一個字串等等。這些相較於一般 UNIX 編輯器(交談式的, 如 vi、emacs)用手動的方式修改文件 , sed 用起來較省力。下面幾節將分別介紹:

   * 何時使用 sed
   * 何處獲得 sed
   * sed 能做那些編輯動作
   * sed 如何工作

1.1 何時使用 sed
 在修改文件時 , 如果不斷地重覆某些編輯動作 , 則可用 sed 自動一次執行這些編輯動作。例如要使 received 檔內 1000 封電子信件內的發信人屬名 "Tom" 改成 "John" , 此時只要在命令列上執行一簡單的 sed 命令就可把檔內所有的 "Tom" 字串替換成 "John"。

 再者 , 當文件需要許多不同編輯動作時 , 則 sed 一次可執行那些不同的編輯動作。例如 sed 能一次執行完將文件中所有空白行刪除、替換字串、並將使用者輸入的文字添加在文件的第六行等等不同的編輯動作。

1.2 何處獲得 sed
 一般的 UNIX 系統 , 本身即附有 sed。不同的 UNIX 系統所附的 sed 版本亦不盡相同。若讀者所使用的 UNIX 系統上未附有 sed , 則可透過 anonymous ftp 到下列地方去取得 :

phi.sinica.edu.tw:/pub/GNU/gnu
gete.sinica.edu.tw:/unix/gnu
ftp.edu.tw:/UNIX/gnu
ftp.csie.nctu.edu.tw:/pub/Unix/GNU
ftp.fcu.edu.tw: /pub3/UNIX/gnu
axp350.ncu.edu.tw:/Packages/gnu
leica.ccu.edu.tw :/pub2/gnu
mail.ncku.edu.tw :/pub/unix/gnu
bbs.ccit.edu.tw :/pub1/UNIX/gnu
prep.ai.mit.edu.tw:/pub/gnu

1.3 sed 能做那些編輯動作
  sed 可刪除(delete)、改變(change)、添加(append)、插入(insert)、合併、交換文件中的資料行 , 或讀入其它檔的資料到文件中 , 也可替換(substuite)它們其中的字串、或轉換(tranfer)其中的字母等等。例如將文件中的連續空白行刪成一行、 "local" 字串替換成 "remote" 、"t" 字母轉換成 "T"、將第 10 行資料與第 11 資料合併等。

1.4 sed 如何工作
 如同其它 UNIX 命令 , sed 由標準輸入讀入編輯文件並由標準輸出送出結果。下圖表示 sed 將資料行 "Unix" 替換成 "UNIX" ,

在 圖中 , 上方 standard input 為標準輸入 , 是讀取資料之處 ; standard output 為標準輸出 , 是送出結果之處 ; 中間 sed 方塊的下面兩個虛線方塊表示 sed 的工作流程。其中 , 左邊虛線方塊表示 sed 將標準輸入資料置入 pattern space , 右邊虛線方塊表示 sed 將 pattern space 中編輯完畢後的資料送到標準輸出。

在虛線方塊中 , 兩個實線方塊分別表示 pattern space 與 sed script。其中 , pattern space 為一緩衝區 , 它是 sed 工作場所 ; 而 sed script 則表示一組執行的編輯指令。

在 圖中, 左邊虛線方塊 "Unix" 由標準輸入置入 pattern space ; 接著 , 在右邊虛線方塊中 , sed 執行 sed script 中的編輯指令 s/Unix/UNIX/ (註解 [2]) , 結果 "Unix" 被替換成 "UNIX" , 之後 , "UNIX" 由 pattern space 送到標準輸出。

 總合上述所言 , 當 sed 由標準輸入讀入一行資料並放入 pattern space 時 , sed 依照 sed script 的編輯指令逐一對 pattern space 內的資料執行編輯 , 之後 , 再由 pattern space 內的結果送到標準輸出 , 接著再將下一行資料讀入。如此重複執行上述動作 , 直至讀完所有資料行為止


2.使用 sed
  Sed 命令列可分成編輯指令與文件檔部份。其中 , 編輯指令負責控制所有的編輯工作 ; 文件檔表示所處理的檔案。sed 的編輯指令均由位址(address)與函數(function)兩部份組成 , 其中 , 在執行時 , sed 利用它的位址參數來決定編輯的對象;而用它的函數參數(註解[3])編輯。

  此外 , sed 編輯指令 , 除了可在命令列上執行 , 也可在檔案內執行。其中差別只是在命令列上執行時 , 其前必須加上選項 -e ; 而在檔案(註解[4])內時 , 則只需在其檔名前加上選項 -f。另外 , sed 執行編輯指令是依照它們在命令列上或檔內的次序。

  下面各節 , 將介紹執行命令列上的編輯指令 、sed 編輯指令、執行檔案內的編輯指令、執行多個檔案的編輯、及執行 sed 輸出控制。

   * 2.1 執行命令列上的編輯指令
   * 2.2 sed 編輯指令
   * 2.3 執行檔案內的編輯指令
   * 2.4 執行多個檔案的編輯
   * 2.5 執行 sed 輸出控制

2.1.執行命令列上的編輯指令
  當編輯指令(參照[section 2.2])在命令列上執行時 , 其前必須加上選項 -e 。其命令格式如下 :

    sed -e '編輯指令1' -e '編輯指令2' ... 文件檔  

其中 , 所有編輯指令都緊接在選項 -e 之後 , 並置於兩個 " ' " 特殊字元間。另外 , 命令上編輯指令的執行是由左而右。

  一般編輯指令不多時 , 使用者通常直接在命令上執行它們。例如 , 刪除 yel.dat 內 1 至 10 行資料 , 並將其餘文字中的 "yellow" 字串改成 "black" 字串。此時 , 可將編輯指令直接在命令上執行 , 其命令如下 :

    sed -e '1,10d' -e 's/yellow/black/g' yel.dat  

在命令中 , 編輯指令 '1,10d'(註解[5])執行刪除 1 至 10 行資料 ; 編輯指令 's/yellow/black/g'(註解[6]) , "yellow" 字串替換(substuite)成 "black" 字串。
2.2 sed 的編輯指令
  sed 編輯指令的格式如下 :

             [address1[,address2]]function[argument]

其中 , 位址參數 address1 、address2 為行數或 regular expression 字串 , 表示所執行編輯的資料行 ; 函數參數 function[argument] 為 sed 的內定函數 , 表示執行的編輯動作。

下面兩小節 , 將仔細介紹位址參數的表示法與有哪些函數參數供選擇。
2.2.1 位址(address)參數的表示法
  實際上 , 位址參數表示法只是將要編輯的資料行 , 用它們的行數或其中的字串來代替表示它們。下面舉幾個例子說明(指令都以函數參數 d(參照[section4.2]) 為例) :

   * 刪除檔內第 10 行資料 , 則指令為 10d。
   * 刪除含有 "man" 字串的資料行時 , 則指令為 /man/d。
   * 刪除檔內第 10 行到第 200 行資料, 則指令為 10,200d。
   * 刪除檔內第 10 行到含 "man" 字串的資料行 , 則指令為 10,/man/d。 

  接下來 , 以位址參數的內容與其個數兩點 , 完整說明指令中位址參數的表示法(同樣也以函數參數 d 為例)。

   * 位址參數的內容:
         o 位址為十進位數字 : 此數字表示行數。當指令執行時 , 將對符合此行數的資料執行函數參數指示的編輯動作。例如 , 刪除資料檔中的第 15 行資料 , 則指令為 15d(參照[section4.2])。其餘類推 ,如刪除資料檔中的第 m 行資料 , 則指令為 md 。

         o 位址為 regular expression(參照[附錄 A]):

           當資料行中有符合 regular expression 所表示的字串時 , 則執行函數參數指示的編輯動作。另外 , 在 regular expression 前後必須加上 "/"。例如指令為 /t.*t/d , 表示刪除所有含兩 "t" 字母的資料行。其中 , "." 表示任意字元; "*" 表示其前字元可重複任意次 , 它們結合 ".*" 表示兩 "t" 字母間的任意字串。 
   * 位址參數的個數 : 在指令中 , 當沒有位址參數時 , 表示全部資料行執行函數參數所指示的編輯動作; 當只有一位址參數時 , 表示只有符合位址的資料行才編輯 ; 當有兩個位址參數 , 如 address1,address2 時 , 表示對資料區執行編輯 , address1 代表起始資料行 , address2 代表結束資料行。對於上述內容 , 以下面例子做具体說明。

        1. 例如指令為

            d 

           其表示刪除檔內所有資料行。
        2. 例如指令為

            5d 

           其表示刪除檔內第五行資料。
        3. 例如指令為

            1,/apple/d

           其表示刪除資料區 , 由檔內第一行至內有 "apple" 字串的資料行。
        4. 例如指令為

           /apple/,/orange/d 

           其表示刪除資料區 , 由檔內含有 "apple" 字串至含有 "orange" 字串的資料行 

2.2.2 有那些函數(function)參數
  下頁表中介紹所有 sed 的函數參數(參照[chapter 4])的功能。
函數參數 功能
: label 建立 script file 內指令互相參考的位置。
#         建立註解
{ }        集合有相同位址參數的指令。
!        不執行函數參數。
=        印出資料行數( line number )。
a/        添加使用者輸入的資料。
b label       將執行的指令跳至由 : 建立的參考位置。
c/       以使用者輸入的資料取代資料。
d       刪除資料。
D       刪除 pattern space 內第一個 newline 字母 / 前的資料。
g       拷貝資料從 hold space。
G       添加資料從 hold space 至 pattern space 。
h       拷貝資料從 pattern space 至 hold space 。
H      添加資料從 pattern space 至 hold space 。
l        印出 l 資料中的 nonprinting character 用 ASCII 碼。
i/       插入添加使用者輸入的資料行。
n       讀入下一筆資料。
N      添加下一筆資料到 pattern space。
p       印出資料。
P       印出 pattern space 內第一個 newline 字母 / 前的資料。
q       跳出 sed 編輯。
r        讀入它檔內容。
s       替換字串。
t label 先執行一替換的編輯指令 , 如果替換成牛p>則將編輯指令跳至 :     label 處執行。
w      寫資料到它檔內。
x      交換 hold space 與 pattern space 內容。
y      轉換(transform)字元。
雖然 , sed 只有上表所述幾個擁有基本編輯功能的函數 , 但由指令中位址參數和指令與指令間的配合 , 也能使 sed 完成大部份的編輯任務。
2.3 執行檔案內的編輯指令
  當執行的指令太多 , 在命令列上撰寫起來十分混亂 , 此時 , 可將這些指令整理儲存在檔案(譬如檔名為 script_file )內 , 用選項 -f script_file , 則讓 sed 執行 script_file 內的編輯指令。其命令的格示如下 :

     sed -f script_file 文件檔  

其中 , 執行 script_file 內編輯指令的順序是由上而下。例如上一節的例子 , 其可改成如下命令:

     sed -f ysb.scr yel.dat  

其中 , ysb.scr 檔的內容如下 :

1,10d
s/yellow/black/g

  另外 , 在命令列上可混合使用選項 -e 與 -f , sed 執行指令順序依然是由命令列的左到右, 如執行至 -f 後檔案內的指令 , 則由上而下執行。

2.4 執行多個文件檔的編輯
  在 sed 命令列上 , 一次可執行編輯多個文件檔 , 它們跟在編輯指令之後。例如 , 替換 white.dat、red.dat、black.dat 檔內的 "yellow" 字串成 "blue" , 其命令如下:

      sed -e 's/yellow/blue/g' white.dat red.dat black.dat 

上述命令執行時 , sed 依 white.dat、red.dat、black.dat 順序 , 執行編輯指令 s/yellow/blue/(請參照[section 4.1] , 進行字串的替換。

2.5.執行輸出的控制
  在命令列上的選項 -n (註解[7]) 表示輸出由編輯指令控制。由前章內容得知 , sed 會 "自動的" 將資料由 pattern space 輸送到標準輸出檔。但藉著選項 -n , 可將 sed 這 "自動的" 的動作改成 "被動的" 由它所執行的編輯指令(註解[8])來決定結果是否輸出。

  由上述可知 , 選項 -n 必須與編輯指令一起配合 , 否則無法獲得結果。例如 , 印出 white.dat 檔內含有 "white" 字串的資料行 , 其命令如下:

      sed -n -e '/white/p' white.dat   

上面命令中 , 選項 -n 與編輯指令 /white/p (參照[section4.6]) 一起配合控制輸出。其中 , 選項 -n 將輸出控制權移給編輯指令;/white/p 將資料行中含有 "white" 字串印出螢幕。



3.範例
  一般在實際使用編輯器的過程中 , 常需要執行替換文件中的字串、搬移、刪除、與搜尋資料行等等動作。當然 , 一般交談式編輯器(如 vi、emacs)都能做得到上述功能 , 但文件一旦有大量上述編輯需求時 , 則用它們編輯十分沒有效率。本章將用舉例的方式說明如何用 sed 自動執行這些編輯功能。此外 , 在本章範例中 , 均以下述方式描述文件的需求 :

           將文件中...資料 , 執行...(動作)

如 此 , 目的是為了能將它們迅速的轉成編輯指令。其中 , " ...資料" 部份 , 轉成指令中的位址參數表示 ; "執行...動作" 部份 , 則轉成函數參數表示 。另外 , 當 "執行...動作" 要由數個函數參數表示時 , 則可利用 "{ "與 " }" 集合這些函數參數(註解[9]) , 其指令形式如下 :

        位址參數{
                函數參數1
                函數參數2
                函數參數3
                    .
                    :
                 }

上述指令表示 , 將對符合位址參數的資料 , 依次執行函數參數1、函數參數2、函數參數3 ... 表示的動作。下面各節 , 分別舉例說明 sed 替換資料、移動、刪除資料、及搜尋資料的命令。

   * 3.1 替換文件中的資料
   * 3.2 搬動文件中的資料
   * 3.3 刪除文件中的資料
   * 3.4 搜尋文件中的資料

3.1 替換文件中的資料
  Sed 可替換文件中的字串、資料行、甚至資料區。其中 , 表示替換字串的指令中的函數參數為 s(參照[section4.1]); 表示替換資料行、或資料區的指令中的函數參數為 c(參照[section4.5])。上述情況以下面三個例子說明。上述情況以下面三個例子說明。

   * 例一. 將文件中含 "machine" 字串的資料行中的 "phi" 字串 , 替換成為 "beta" 字串。其命令列如下 :
     sed -e '/machine/s/phi/beta/g' input.dat(以後文件檔都以 input.dat 代表)

   * 例二. 將文件中第 5 行資料 , 替換成句子 "Those who in quarrels interpose, must often wipe a bloody nose."。其命令列如下

     sed -e '5c/
     Those must often wipe a bloody nose.
     ' input.dat

   * 例三. 將文件中 1 至 100 行的資料區 , 替換成如下兩行資料 :

     How are you?
     data be deleted!

     則其命令列如下

     sed -e '1,100c/
     How are you?/
     data be deleted!
     ' input.dat

3.2 搬動文件中的資料
  使用者可用 sed 中的 hold space 暫存編輯中的資料、用函數參數 w(參照[section4.9])將文件資料搬動到它檔內儲存、或用函數參數 r(參照[section4.8])將它檔內容搬到文件內。Hold space 是 sed 用來暫存 pattern space 內資料的暫存器 , 當 sed 執行函數參數 h、H(參照[section4.19])時 , 會將 pattern space 資料暫存到 hold space;當執行函數參數 x、g、G(參照[section4.22])時 , 會將暫存的資料取到 pattern space 。下面舉三個例子說明。

   * 例一. 將文件中的前 100 資料 , 搬到文件中第 300 後輸出。其命令列如下 :

     sed -f mov.scr 文件檔

     mov.scr 檔的內容為

     1,100{
     H
     d
     }
     300G

     其中 ,

      
     1,100{
     H
     d
     }

     它表示將文件中的前 100 資料 , 先儲存(參照[section4.19])在 hold space 之後刪除 ;指令 300G (參照[section4.22]) 表示 , 將 hold space 內的資料 , 添加在文件中的第 300 資料後輸出。
   * 例二. 將文件中含 "phi" 字串的資料行 , 搬至 mach.inf 檔中儲存。其命令列如下 :

     sed -e '/phi/w mach.inf' 文件檔

   * 例三. 將 mach.inf 檔內容 , 搬至文件中含 "beta" 字串的資料行。其命令列如下 :

     sed -e '/beta/r mach.inf' 文件檔

另外 , 由於 sed 是一 stream(參照[section1.4])編輯器 , 故理論上輸出後的文件資料不可能再搬回來編輯。

3.3 刪除文件中的資料
  因為 sed 是一行編輯器 , 所以 sed 很容易刪除個別資料行或整個資料區。一般用函數參數 d(參照[section4.2])或 D(參照[section4.17]) 來表示。下面舉兩個例子說明。

   * 將文件內所有空白行全部刪除。其命令列為

           sed -e '/^$/d' 文件檔

     regular expression(註解[附錄 A]) , ^$ 表示空白行。 其中 , ^ 限制其後字串必須在行首; $ 限制其前字串必須在行尾。
   * 將文件內連續的空白行 , 刪除它們成為一行。其命令列為

        sed -e '/^$/{
        N
        /^$/D 
        }' 文件檔

     其中 , 函數參數 N(參照[section4.16]) 表示 , 將空白行的下一行資料添加至 pattern space 內。函數參數 /^$/D 表示 , 當添加的是空白行時 , 刪除第一行空白行 , 而且剩下的空白行則再重新執行指令一次。指令重新執行一次 , 刪除一行空白行 , 如此反覆直至空白行後添加的為非空白行為止 , 故連續的空白行最後只剩一空白行被輸出。 

3.4 搜尋文件中的資料
  Sed 可以執行類似 UNIX 命令 grep 的功能。理論上 , 可用 regular expression(參照[附錄 A])。例如 , 將文件中含有 "gamma" 字串的資料行輸出。則其命令列如下:

                sed -n -e '/gamma/p' 文件檔

  但是 , sed 是行編輯器 , 它的搜尋基本上是以一行為單位。因此 , 當一些字串因換行而被拆成兩部份時 , 一般的方法即不可行。此時 , 就必須以合併兩行的方式來搜尋這些資料。其情況如下面例子:

例. 將文件中含 "omega" 字串的資料輸出。其命令列如下

sed -f gp.scr 文件檔

gp.scr 檔的內容如下 :

/omega/b
N
h
s/.*/n//
/omega/b
g
D

在 上述 sed script(註解[10]), 因藉著函數參數 b 形成類似 C 語言中的 case statement 結構 , 使得 sed 可分別處理當資料內含 "omega" 字串 ; 當 "omega" 字串被拆成兩行 ; 以及資料內沒有"omega" 字串的情況。接下來就依上述的三種情況 , 將 sed script 分成下面三部份來討論。

  1. 當資料內含 "omega" , 則執行編輯指令

     /omega/b

     它表示當資料內含 "omega" 字串時 , sed 不用再對它執行後面的指令 , 而直接將它輸出。
  2. 當資料內沒有"omega" , 則執行編輯指令如下

     N
     h
     s/.*/n//
     /omega/b

     其中 , 函數參數 N(參照[section 4.16]) , 它表示將下一行資料讀入使得 pattern space 內含前後兩行資料 。函數參數 h(參照[section 4.19]) , 它表示將 pattern space 內的前後兩行資料存入 hold space 。函數參數 s/.*/n// , 它表示將 pattern space 內的前後兩行資料合併(註解[11])成一行。/omega/b , 它表示如果合併後的資料內含 "omega" 字串 , 則不用再執行它之後的指令 , 而將此資料自動輸出 ;

  3. 當合併後的資料依舊不含 "omega" , 則執行編輯指令如下

     g
     D

     其中 , 函數參數 g(參照[section4.21]) , 它表示將 hold space 內合併前的兩行資料放回 pattern space。 函數參數 D(參照[section4.17]) , 它表示刪除兩行資料中的第一行資料 , 並讓剩下的那行資料 , 重新執行 sed script。如此 , 無論的資料行內或行間的字串才可搜尋完全。


介紹函數參數

介紹函數參數
  本章將以一節一個函數參數的方式 ,介紹所有 sed 提供的函數參數 , 其中有

| s | d | a | i | c | p | l | r | w | y | ! | n | q | = | # | N | D | P | h | H | g | G | x | b | t |

另外 , 在各節中 , 首先簡單介紹函數參數功能 , 接著說明函數參數與位址參數配合的格式 , 而其中也一併描述 sed 執行此函數參數的工作情形。
4.1 s
  函數參數 s 表示替換(substitute)文件內字串。其指令格式如下 :
[address1[ ,address2]] s/pattern/replacemen/[flag]

對上述格式有下面幾點說明 :

  1. 函數參數 s 最多與兩個位址參數配合。
  2. 關於 "s/pattern/replacement/[flag]"(註解[12]) 有下面幾點說明:
         * pattern : 它為 reguler expression 字串。它表示文件中要被替換的字串。
         * replacement : 它為一般字串。但其內出現下列字元有特別意義 :

              1. & : 代表其前 pattern 字串。例如

                 sed -e 's/test/& my car/' 資料檔名    

                 指令中 , & 代表 pattern 字串 "test"。故執行後 , 資料檔的 "test" 被替換成 "test my car"。
              2. /n : 代表 pattern 中被第 n 個 /( 、/)(參照[附錄 A]) 所括起來的字串。例如

                 sed -e  's//(test/) /(my/) /(car/)/[/2 /3 /1]/' 資料檔名    

                 指令中 , /1 表示 "test"、/2 表示 "my"、/1 表示 "car" 字串。故執行後 , 資料檔的 "test my car" 被替換成 "[my car test]"。
              3. / : 可用它來還原一些特殊符號(如上述的 & 與 / )本身字面上的意義 , 或用它來代表換行。 
         * flag : 主要用它來控制一些替換情況 :
               o 當 flag 為 g 時 , 代表替換所有符合(match)的字串 。
               o 當 flag 為十進位數字 m 時 , 代表替換行內第 m 個符合的字串。
               o 當 flag 為 p 時 , 代表替換第一個符合 pattern 的字串後 , 將資料輸出標準輸出檔。
               o 當 flag 為 w wfile 時 , 代表替換第一個符合 pattern 的字串後 , 輸出到 wfile 檔內(如果 wfile 不存在 , 則會重新開啟名為 wfile 的檔案)。
               o 當沒有 flag 時 , 則將資料行內第一個符合 pattern 的字串以 replacement 字串來替換 。 
         * delimiter : 在 "/pattern/replace/[flag] " 中 "/" 被當成一 delimiter。除了空白(blank)、換行(newline) 之外 , 使用者可用任何字元作為 delimiter。例如下述編輯指令

                   s#/usr#/usr1#g

           上述命令中 /verb|#| 為 delimiter。如果用 "/" 做 delimiter , 則 sed 會將 pattern 與 replacement 中的 "/" 當成 delimiter 而發生錯誤。 
  3. 範例:
         * 題目 : 替換 input.dat 檔(後面如果沒有特別指定 , 均假設文件檔名為 input.dat)內 "1996" 字串成 "1997" , 同時將這些資料行存入 year97.dat 檔內。
         * 說明 : 用函數參數 s 指示 sed 將 "1996" 字串替換成 "1997" , 另外用 s argument 中的 flag w 指示 sed 將替換過的資料行存入 year97.dat 檔內。
         * sed 命令列:

           sed -e 's/1996/1997/w year97.dat' input.dat

4.2 d
函數參數 d 表示刪除資料行 , 其指令格式如下:


      [address1[ ,address2]] d


對上述格式有下面幾點說明:

  1. 函數參數 d 最多與兩個位址參數配合。
  2. sed 執行刪除動作情況如下 :
        1. 將 pattern space 內符合位址參數的資料刪除。
        2. 將下一筆資料讀進 pattern space 。
        3. 重新執行 sed script。 
  3. 範例 : 可參考 section 3.3。 

4.3 a
函數參數 a 表示將資料添加到文件中。其指令格式如下:

      [address1] a/        使用者所輸入的資料

對上述格式有下面幾點說明:

  1. 函數參數 a 最多與一個位址參數配合。
  2. 函數參數 a 緊接著 "/" 字元用來表示此行結束 , 使用者所輸入的資料必須從下一行輸入。如果資料超過一行 , 則須在每行的結尾加入"/"。
  3. sed 執行添加動作情況如下 : 當 pattern space 內資料輸出後 , sed 跟著輸出使用者所輸入的資料。
  4. 範例 :
         * 題目: 添加 "多工作業系統" 在含 "UNIX" 字串的資料行後。假設 input.dat 檔的內容如下 :

           UNIX

         * 說明: 用函數參數 a 將所輸入的資料添加在含 "UNIX" 字串的資料行後。
         * sed 命令列如下 :

           sed -e '/UNIX/a/
           多工作業系統
           ' input.dat 

           執行上述命令後 , 其輸出結果如下 :

           UNIX
           多工作業系統

4.4 i
函數參數 i 表示將資料插入文件中。其指令格式如下:

      [address1] i/        使用者所輸入的資料


對上述格式有下面幾點說明:

  1. 函數參數 i 最多與一個位址參數配合。
  2. 函數參數 i 緊接著 "/" 字元用來表示此行結束 , 使用者所輸入的資料必須從下一行輸入。如果資料超過一行 , 則須在每行的結尾加入"/"。
  3. sed 執行插入動作的情況如下 : 在 pattern space 內資料輸出前 , sed 先輸出使用者所輸入的資料。
  4. 範例 :
         * 題目: 將 "文章版權屬於中央研究院" 插在 input.dat 檔中含 "院長 : 李遠哲" 的資料行之前。假設 input.dat 檔內容如下 :

           院長 : 李遠哲

         * 說明: 用函數參數 i 將資料行 "文章版權屬於中央研究院" 插在含 "院長 : 李遠哲" 的資料行之前。
         * sed 命令列如下:

           sed -e '/院長 : 李遠哲/i/
           文章版權屬於中央研究院
           ' input.dat

           執行上述命令後的輸出如下 :

           文章版權屬於中央研究院
           院長 : 李遠哲

4.5 c
函數參數 c 表示改變文件中的資料。其格式如下:

    [address1[ ,address2]]c/      使用者所輸入的資料


對上述格式有下面幾點說明:

   * 函數參數 c 最多與兩個位址參數配合。
   * 函數參數 c 緊接著 "/" 字元用來表示此行結束 , 使用者所輸入的資料必須從下一行輸入。如果資料超過一行 , 則須在每行的結尾加入"/"。
   * sed 執行改變動作的情況 : 在 pattern space 內資料輸出時 , sed 改變它成為使用者所輸入的資料。
   * 範例 : 參考 section 3.1 之例二、三。 

4.6 p
函數參數 p 表示印出資料。其指令格式如下 :

    [address1[ , address2]] p


對於上述格式有下面幾點說明 :

  1. 函數參數 p 最多與兩個位址參數配合。
  2. sed 執行印出動作的情況如下 : sed 拷備一份 pattern space 內容至標準輸出檔。
  3. 範例 : 參考 section 3.4 開頭的內容。 

4.7 l
函數參數 l , 除可將資料中的 nonprinting character 以 ASCII碼列出外 , 其於均與函數參數 p 相同。例如 , 將下面 input.dat 檔中的 ^[ 以 ASCII 碼印出

The Great ^[ is a movie starring Steve McQueen.

執行命令 sed -e 'l' input.dat 後 , 則輸出結果如下 :

The Great /003 is a movie starring Steve McQueen.
The Great     is a movie starring Steve McQueen.

上述第二行資料為 sed 的自動輸出(請參照註解[]。
4.8 r
函數參數 r 表示讀入它檔案內容到文件中。其指令格式如下 :

      [address1] r 它檔名稱


對於上述格式有下面幾點說明 :

  1. 函數參數 r 最多與一個位址參數配合。
  2. 在指令中 , 函數參數 r 與它檔名稱間 , 只能有一空格。
  3. sed 執行讀入動作的情況如下 : 在 pattern space 內資料輸出後 , sed 讀出它檔的內容跟著輸出。當它檔不存在時 , sed 照樣執行其它指令而不會有任何錯誤訊息產生。
  4. 範例 : 參考 section 3.1 之例三。 

4.9 w
函數參數 w 表示將文件中的寫到它檔內。其指令格式如下 :

    [address1[ ,address2]] w 它檔名稱


對於上述格式有下面幾點說明 :

  1. 函數參數 w 最多與兩個位址參數配合。
  2. 在指令中 , 函數參數 w 與它檔名稱間 , 只能有一空格。
  3. sed 執行寫出動作的情況如 : 將 pattern space 內資料寫到它檔內。資料寫入時 , 會取代(overwrite)原來檔案內的資料。另外 , 當它檔不存在時 , sed 會重新產生(creat)它。
  4. 範例:參考 section 3.1 之例二。 

4.10 y
函數參數 y 表示轉換資料中的字元。其指令格式如下 :

    [address1[ ,address2]]y /xyz.../abc.../


對於上述格式有下面幾點說明 :

  1. 函數參數最多配合兩個位址參數。
  2. 指令中 , /abc.../xyz.../(x、y、z、a、b、c 代表某些字元) 為 y 的 argument 。其中 abc... 與 xyz... 的字元個數必須相同。
  3. sed 執行轉換時 , 將 pattern space 內資料內的 a 字元轉換成 x 字元 、b 字元轉換成 y 字元 、c 字元轉換成 z 字元 ...。
  4. 範例:
         * 題目: 將 input.dat 檔中的小寫字母改成大寫。假設 input.dat 檔的內容如下 :

           Sodd's Second Law:
                   Sooner or later, the worst possible set of 
                   circumstances is bound to occur.

         * 說明:利用函數參數 y 指示 sed 做字母大小的轉換。
         * sed 命令列如下 :

            sed -e '
           y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
           ' input.dat

           執行上述命令輸出結果如下 :

           SODD'S SECOND LAW:
                   SOONER OR LATER, THE WORST POSSIBLE SET OF 
                   CIRCUMSTANCES IS BOUND TO OCCUR.

4.11 !
函數參數 ! 表示不執行函數參數。當有如下指令時 ,

    [address1[ , address2]] ! 函數參數


表示 , 對符合位址參數之資料不執行函數參數。例如刪除 , 除了含 "1996" 字串 , 所有資料行 , 則執行如下命令

sed -e '/1996/!d' input.dat

4.12 n
函數參數 n 表示讀入下一行資料。其指令格式如下:

    [address1[ ,address2]] n


對上述格式有下面幾點說明 :

  1. 函數參數 n 最多配合兩個位址參數。
  2. sed 執行讀入下一行動作的情況如下 :
        1. 輸出在 pattern space 的資料。
        2. 將下一筆資料讀到 pattern space。
        3. 執行下一個編輯指令。 
  3. 範例(可與[section4.18]中的範例比較):
         * 題目 : 輸出 input.dat 檔內偶數行資料。假設 input.dat 檔內容如下:

           The
           UNIX
           Operation
           System

         * 說明: 在命令列上
              1. 以選項 -n , 將資料輸出的控制權(參照[section2.5])轉給指令。
              2. 利用函數參數 n 將下一行資料(偶數行)取代 pattern space 內的資料行(奇數行)。
              3. 利用函數參數 p 將 pattern space 內的資料(偶數行)輸出。 
           最後 , 整個輸出只有原先檔內的偶數行資料。
         * sed 命令列如下 :

           sed -n -e 'n' -e 'p' infro.dat

           執行上述命令後 , 輸出的結果如下 :

           UNIX
           System

4.13 q
函數參數 q 表示跳離 sed 。其指令格式如下:

    [address1] q


對上述格式有下面幾點說明 :

  1. 函數參數 q 最多配合一個位址參數。
  2. sed 執行跳離動作時 , 它停止輸入 pattern space 資料 , 同時停止資料送到標準輸出檔。
  3. 範例 :
         * 題目: 對文件檔執行 script_file 內的編輯指令 , 除非遇到 "Linux" 字串。
         * 說明: 無論 script_file 內是何種指令 , 使用者只要在命令列上用指令/Linux/q , 函數參數 q 會強迫 sed 遇到 "Linux" 時做跳離動作。
         * sed 命令列如下 :

           sed -e '/Linux/q' -f script_file  input.dat

4.14 =
函數參數 = 表示印出資料的行數。其指令格式如下:

    [address1 ,[address2]] =


對上述格式有下面幾點說明 :

  1. 函數參數 = 最多配合兩個位址參數。
  2. 執行時 , 行數將在資料輸出前先輸出。
  3. 範例 :
         * 題目: 印出 input.dat 檔內資料行數。假設 input.dat 的內容如下 :

           The UNIX
           Operating System

         * 說明 : 用函數參數 = 來印出資料的行數。
         * sed 命令列如下 :

            sed -e '=' input.dat

           執行上述命令後 , 輸出的結果如下 :

           1
           The UNIX
           2
           Operating System

4.15 #
在 script file 內 , 函數參數 # 後的文字為注解。當注解文字超過多行時 , 其行間須以 "/" 換行字元相隔。

4.16 N
函數參數 N 表示添加下一筆資料在 pattern space 內。其指令格式如下:

    [address1 ,[address2]] N


對上述格式有下面幾點說明 :

  1. 函數參數 N 最多配合兩個位址參數。
  2. sed 執行時 , 將下一行資料讀入並添加在 pattern space 內 , 資料行間以換行字元(embedded newline character)分隔。此外 , 在替換時 , 換行字元可用 /n 來 match。
  3. 範例 :
         * 題目: 將下述兩行資料合併。假設 input.dat 的內容如下 :

           The UNIX
           Operating System

         * 說明 : 先利用函數參數 N 將兩行資料置於 pattern space 內 , 在利用函數參數 s//n/ / 將兩行資料間的分隔號 /n 以空白替代 , 如此兩行資料變成一行輸出。
         * sed 命令列如下 :

            sed -e 'N' -e 's//n/ /' input.dat

           執行上述命令後 , 其輸出的結果如下:

           The UNIX Operating System

4.17 D
函數參數 D 表示刪除 pattern space 內的第一行資料。其指令格式如下:

    [address1,address2]D


對上述格式有下面幾點說明 :

  1. 函數參數 D 最多配合兩個位址參數。
  2. 函數參數 D 與 d 的比較如下 :
        1. 當 pattern space 內只有一資料行時 , D 與 d 作用相同。
        2. 當 pattern space 內有多行資料行時
              1. D 表示只刪除 pattern space 內第一行資料 ; d 則全刪除。
              2. D 表示執行刪除後 , pattern space 內不添加下一筆資料 , 而將剩下的資料重新執行 sed script ; d 則讀入下一行後執行 sed script。 
  3. 範例 : 參考 section 3.3 的第二個例子。 

4.18 P
函數參數 P 表示印出 pattern space 內的第一行資料。其指令格式如下:

    [address1,address2] P


對上述格式有下面幾點說明 :

  1. 函數參數 P 最多配合兩個位址參數。
  2. P 與 p , 除了面對的 pattern space 內的資料行數不同外 , 其它均相同。
  3. 範例(可與[section4.12]中的範例):
         * 題目 : 輸出 input.dat 檔內奇數行資料。假設 input.dat 檔內容如下:

           The
           UNIX
           System

         * 說明: 在命令列上
              1. 以選項 -n , 將資料輸出的控制權(參照[section2.5])轉給指令。
              2. 利用函數參數 N 將偶數行添加至 pattern space 內奇數行後。
              3. 利用函數參數 P 將 pattern space 內的第一行(奇數行)輸出。 
           在奇數行輸出後 , pattern space 內剩下的資料行(偶數行)則被放棄輸出。最後 , 整個輸出只有原先的奇數行資料。
         * sed 命令列 :

           sed -n -e 'N' -e 'P' infro.dat

           執行上述命令後 , 輸出的結果如下 :

           The
           System

4.19 h
函數參數 h 表示暫存 pattern space 的資料至 hold space。其指令格式如下:

    [address1 ,[address2]] h


對上述格式有下面幾點說明 :

  1. 函數參數 h 最多配合兩個位址參數。
  2. sed 執行暫存動作時 , 會蓋掉(overwrite) hold space 內原來的資料。
  3. 當 sed 全部執行結束時 , hold space 內資料會自動清除。
  4. 範例 :參考 section 3.4 的例子。 

4.20 H
函 數參數 H 與 h 唯一差別是 , sed 執行 h 時 , 資料蓋掉(overwrite) hold space 內原來的資料 , 而 H , 資料則是 "添加(append)" 在 hold space 原來資料後。例題請參考 section 3.2 之例一。
4.21 g
  函數參數 g 表示與函數參數 h 相反的動作 , 它表示將 hold space 內資料放回 pattern space 內。其指令格式如下 :

    [address1,address2]g


  1. 函數參數 g 最多配合兩個位址參數。
  2. sed 執行放回動作時 , 資料蓋掉(overwrite)(註解[13]) pattern space 內原來的資料。
  3. 例題 :參考 section 3.4 的例子。 

4.22 G
函 數參數 G 與 g 唯一差別是 , sed 執行 g 時 , 資料蓋掉(overwrite) pattern space 內原來的資料 , 而 G , 資料則是 "添加(append)" 在 pattern space 原來資料後。例子請參考 section 3.2 例一。
4.23 x
  函數參數 x 表示交換 hold space 與 pattern space 內的資料。其指令格式如下 :

    [address1 ,[address2]] x


函 數參數 x 大部份與其它處理 hold space 的函數參數一起配合。例如 , 將 input.dat 檔內第 1 行資料取代第 3 行資料。此時 , 用函數參數 h 與 x 來配合。其中 , 以函數參數 h 將第 1 資料存入 hold space ; 當第 3 行資料出現在 pattern space , 以函數參數 x 交換 hold space 與 pattern space 的內容。如此 , 第 3 行資料就被第 1 資料替代。其命令列如下:

sed -e '1h' -e '3x' input.dat

4.24 b、:label
函 數參數 : 與函數參數 b 可在 sed script 內建立類似 BASIC 語言中 GOTO 指令的功能。其中 , 函數參數 : 建立標記;函數參數 b 將下一個執行的指令 branch 到標記處執行。函數參數 : 與 b , 在 script file 內配合的情況如下

   
                  .
                  .
                  .
             編輯指令m1
             :記號
             編輯指令m2
                  .
                  .
                  .               
             [address1,[address2]]b [記號]                  

其 中 , 當 sed 執行至指令 [address1,[address2]]b [記號] 時 , 如 pattern space 內的資料符合位址參數 , 則 sed 將下一個執行的位置 branch 至由 :記號(註解[14]) 設定的標記處 , 也就是再由 "編輯指令m2" ... 執行。另外 , 如果指令中函數參數 b 後沒有記號 , 則 sed 將下一個執行的指令 branch 到 script file 的最後 , 利用此可使 sed script 內有類似 C 語言中的 case statement 結構。
範例 :

   * 題目: 將 input.dat 檔內資料行的開頭字母重覆印 40 次。假設 input.dat 檔的內容如下 :

     A
     B
     C

   * 說明: 用指令 b p1 與 :p1 構成執行增加字母的迴圈(loop) , 同時在字母出現 40 個時 , 也用指令 b 來跳出迴圈。下面就以檔內第一行資料 "A" 為例 , 描述它如何連續多添加 39 個 "A" 在同一行:
        1. 用指令 s/A/AA/(參照 section4.1)將 "A" 替換成 "AA"。
        2. 用指令 b p1 與 :p1 構成迴圈(loop) , 它目的使上述動作被反覆的執行。每執行一次迴圈 , 則資料行上的 "A" 就多出一個。例如 , 第一次迴圈資料行變成 "AA" , 第二次迴圈資料行變成 "AAA" ...。
        3. 用指令 [ABC]/{40/}/b(註解[15]) 來作為停止迴圈的條件。當資料行有連續 40 個 A 出現時 , 函數參數 b 將執行的指令跳到最後 , 停止對此行的編輯。 
     同樣 , 對其它資料行也如同上述的方式執行。
   * sed 命令列如下 :

     sed -e '{
     :p1
     /A/s/A/AA/
     /B/s/B/BB/
     /C/s/C/CC/
     /[ABC]/{40/}/b
     b p1
     }' input.dat

4.25 t
基本上 , 函數參數 t 與 函數參數 b 的功能類似 , 除了在執行 t 的 branch 前 , 會先去測試其前的替換指令有沒有執行替換成功外。在 script file 內的情況如下:

                  .
                  .
                  .
             編輯指令m1
             :記號
             編輯指令m2
                  .
                  .
                  .
             s/.../.../
             [address1,[address2]]t [記號]
             編輯指令m3

其中 , 與函數參數 b 不同處在於 , 執行函數參數 t branch 時 , 會先檢查其前一個替換指令成功與否。如成功 , 則執行 branch ; 不成功 , 則不 branch , 而繼續執行下一個編輯指令 , 例如上面的編輯指令m3。
範例:

   * 題目 : 將 input.dat 檔中資料 A1 替換成 C1、C1 替換成 B1、B1 替換成 A1。input.dat 檔的內容如下:

     代號
      B1
      A1
      B1
      C1 
      A1
      C1

   * 說明 : input.dat 檔中全部資料行只需要執行一次替換動作 , 但為避免資料被替換多次 , 所以利用函數參數 t 在 sed script 內形成一類似 C 語言中 case statement 結構 , 使每行資料替換一次後能立即用函數參數 t 跳離替換編輯。
   * sed 命令列 :

     sed -e '{
     s/A1/C1/
     t
     s/C1/B1/
     t
     s/B1/A1/
     t
     }' input.dat

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值