SED 手冊
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 內的結果送到標準輸出 , 接着再將下一行資料讀入。如此重執行上述動作 , 直至讀完所有資料行爲止。
使用 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 爲例)。
位址參數的內容:
位址爲十進位數字 : 此數字表示行數。當指令執行時 , 將對符合此行數的資料執行函數參數指示的編輯動作。例如,刪除資料檔中的第 15 行資料 , 則指令爲 15d(參照[section4.2])。其餘類推 ,如刪除資料檔中的第 m 行資料 , 則指令爲 md 。
位址爲 regular expression(參照[附錄 A]):
當資料行中有符合 regular expression 所表示的字串時 , 則執行函數參數指示的編輯動作。另外 , 在 regularexpression 前後必須加上 "/"。例如指令爲 /t.*t/d , 表示刪除所有含兩 "t" 字母的資料行。其中 , "." 表示任意字元; "*" 表示其前字元可重任意次 , 它們結合 ".*" 表示兩 "t" 字母間的任意字串。
位址參數的個數 : 在指令中 , 當沒有位址參數時 , 表示全部資料行執行函數參數所指示的編輯動作; 當只有一位址參數時 , 表示只有符合位址的資料行才編輯 ; 當有兩個位址參數 , 如 address1,address2 時 , 表示對資料區執行編輯 , address1 代表起始資料行 , address2 代表結束資料行。對於上述內容 , 以下面例子做具說明。
例如指令爲
d
其表示刪除檔內所有資料行。
例如指令爲
5d
其表示刪除檔內第五行資料。
例如指令爲
1,/apple/d
其表示刪除資料區 , 由檔內第一行至內有"apple" 字串的資料行。
例如指令爲
/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 資料中的 nonprintingcharacter 用 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.datblack.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, mustoften 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 分成下面三部份來討論。
當資料內含 "omega" , 則執行編輯指令
/omega/b
它表示當資料內含 "omega" 字串時 , sed 不用再對它執行後面的指令 , 而直接將它輸出。
當資料內沒有"omega" , 則執行編輯指令如下
N
h
s/.*n//
/omega/b
其中 , 函數參數 N(參照[section 4.16]) , 它表示將下一行資料讀入使得 patternspace 內含前後兩行資料 。函數參數 h(參照[section 4.19]) , 它表示將 pattern space 內的前後兩行資料存入 hold space 。函數參數 s/.*n// , 它表示將 pattern space 內的前後兩行資料合(解[11])成一行。/omega/b , 它表示如果合後的資料內含 "omega" 字串 , 則不用再執行它之後的指令 , 而將此資料自動輸出 ;
當合後的資料依舊不含 "omega" , 則執行編輯指令如下
g
D
其中 , 函數參數 g(參照[section4.21]) , 它表示將 hold space 內合前的兩行資料放回 pattern space。 函數參數 D(參照[section4.17]) , 它表示刪除兩行資料中的第一行資料 , 並讓剩下的那行資料 , 重新執行 sed script。如此 , 無論的資料行內或行間的字串纔可搜尋完全。
4.介紹函數參數
本章將以一節一個函數參數的方式 ,介紹所有 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]
對上述格式有下面幾點說明 :
函數參數 s 最多與兩個位址參數配合。
關於 "s/pattern/replacement/[flag]"(解[12]) 有下面幾點說明:
pattern : 它爲 reguler expression 字串。它表示文件中要被替換的字串。
replacement : 它爲一般字串。但其內出現下列字元有特別意義 :
& : 代表其前 pattern 字串。例如
sed -e 's/test/& my car/' 資料檔名
指令中 , & 代表 pattern 字串 "test"。故執行後 , 資料檔的 "test" 被替換成 "test my car"。
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]"。
: 可用它來還原一些特殊符號(如上述的 & 與 )本身字面上的意義 , 或用它來代表換行。
flag : 主要用它來控制一些替換情況 :
當 flag 爲 g 時 , 代表替換所有符合(match)的字串 。
當 flag 爲十進位數字 m 時 , 代表替換行內第 m 個符合的字串。
當 flag 爲 p 時 , 代表替換第一個符合 pattern 的字串後 , 將資料輸出標準輸出檔。
當 flag 爲 w wfile 時 , 代表替換第一個符合 pattern 的字串後 , 輸出到 wfile 檔內(如果 wfile 不存在 , 則會重新開啓名爲 wfile 的檔案)。
當沒有 flag 時 , 則將資料行內第一個符合 pattern 的字串以 replacement 字串來替換 。
delimiter : 在 "/pattern/replace/[flag] " 中 "/" 被當成一 delimiter。除了空白(blank)、換行(newline) 之外 , 使用者可用任何字元作爲 delimiter。例如下述編輯指令
s#/usr#/usr1#g
上述命令中 verb|#| 爲 delimiter。如果用 "/" 做 delimiter , 則 sed 會將 pattern 與 replacement 中的 "/" 當成 delimiter 而發生錯誤。
例:
題目 : 替換 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
對上述格式有下面幾點說明:
函數參數 d 最多與兩個位址參數配合。
sed 執行刪除動作情況如下 :
將 pattern space 內符合位址參數的資料刪除。
將下一筆資料讀進 pattern space 。
重新執行 sed script。
例 : 可參考 section 3.3。
4.3 a
函數參數 a 表示將資料添加到文件中。其指令格式如下:
[address1] a 使用者所輸入的資料
對上述格式有下面幾點說明:
函數參數 a 最多與一個位址參數配合。
函數參數 a 緊接着 "" 字元用來表示此行結束 , 使用者所輸入的資料必須從下一行輸入。如果資料超過一行 , 則須在每行的結尾加入""。
sed 執行添加動作情況如下 : 當 pattern space 內資料輸出後 , sed 跟着輸出使用者所輸入的資料。
例 :
題目: 添加 "多工作業系統" 在含 "UNIX" 字串的資料行後。假設 input.dat 檔的內容如下 :
UNIX
說明: 用函數參數 a 將所輸入的資料添加在含 "UNIX" 字串的資料行後。
sed 命令列如下 :
sed -e '/UNIX/a
多工作業系統
' input.dat
執行上述命令後 , 其輸出結果如下 :
UNIX
多工作業系統
4.4 i
函數參數 i 表示將資料插入文件中。其指令格式如下:
[address1]i 使用者所輸入的資料
對上述格式有下面幾點說明:
函數參數 i 最多與一個位址參數配合。
函數參數 i 緊接着 "" 字元用來表示此行結束 , 使用者所輸入的資料必須從下一行輸入。如果資料超過一行 , 則須在每行的結尾加入""。
sed 執行插入動作的情況如下 : 在 pattern space 內資料輸出前 , sed 先輸出使用者所輸入的資料。
例 :
題目: 將 "文章版權屬於中央研究院" 插在 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
對於上述格式有下面幾點說明 :
函數參數 p 最多與兩個位址參數配合。
sed 執行印出動作的情況如下 : sed 拷備一份 pattern space 內容至標準輸出檔。
例 : 參考 section 3.4 開頭的內容。
4.7 l
函數參數 l , 除可將資料中的 nonprinting character 以 ASCII碼列出外 , 其於均與函數參數 p 相同。例如 , 將下
面 input.dat 檔中的 ^[ 以 ASCII 碼印出
The Great ^[ is amovie starring Steve McQueen.
執行命令 sed -e 'l' input.dat 後 , 則輸出結果如下 :
The Great 03 is a movie starring Steve McQueen.
The Great is a movie starring Steve McQueen.
上述第二行資料爲 sed 的自動輸出(請參照解[]。
4.8 r
函數參數 r 表示讀入它檔案內容到文件中。其指令格式如下:
[address1] r 它檔名稱
對於上述格式有下面幾點說明 :
函數參數 r 最多與一個位址參數配合。
在指令中 , 函數參數 r 與它檔名稱間 , 只能有一空格。
sed 執行讀入動作的情況如下 : 在 pattern space 內資料輸出後 , sed 讀出它檔的內容跟着輸出。當它檔不存在時 , sed 照樣執行其它指令而不會有任何錯誤訊息產生。
例 : 參考 section 3.1 之例三。
4.9 w
函數參數 w 表示將文件中的寫到它檔內。其指令格式如下:
[address1[ ,address2]] w 它檔名稱
對於上述格式有下面幾點說明 :
函數參數 w 最多與兩個位址參數配合。
在指令中 , 函數參數 w 與它檔名稱間 , 只能有一空格。
sed 執行寫出動作的情況如 : 將 pattern space 內資料寫到它檔內。資料寫入時 , 會取代(overwrite)原來檔案內的資料。另外 , 當它檔不存在時 , sed 會重新產生(creat)它。
例:參考 section 3.1 之例二。
4.10 y
函數參數 y 表示轉換資料中的字元。其指令格式如下:
[address1[ ,address2]]y /xyz.../abc.../
對於上述格式有下面幾點說明 :
函數參數最多配合兩個位址參數。
指令中 , /abc.../xyz.../(x、y、z、a、b、c 代表某些字元) 爲 y 的 argument 。其中 abc... 與 xyz... 的字元個數必須相同。 sed 執行轉換時 , 將 pattern space 內資料內的 a 字元轉換成 x 字元 、b 字元轉換成 y 字元 、c 字元轉換成 z 字元 ...。
例:
題目: 將 input.dat 檔中的小寫字母改成大寫。假設 input.dat 檔的內容如下 :
Sodd's Second Law:
Sooner or later, the worst possibleset 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 POSSIBLESET OF
CIRCUMSTANCES IS BOUND TO OCCUR.
4.11 !
函數參數 ! 表示不執行函數參數。當有如下指令時,
[address1[ , address2]] ! 函數參數
表示 , 對符合位址參數之資料不執行函數參數。例如刪除 ,除了含 "1996" 字串 , 所有資料行 , 則執行如下命令
sed -e '/1996/!d'input.dat
4.12 n
函數參數 n 表示讀入下一行資料。其指令格式如下:
[address1[ ,address2]] n
對上述格式有下面幾點說明 :
函數參數 n 最多配合兩個位址參數。
sed 執行讀入下一行動作的情況如下 :
輸出在 pattern space 的資料。
將下一筆資料讀到 pattern space。
執行下一個編輯指令。
例(可與[section4.18]中的例比較):
題目 : 輸出 input.dat 檔內偶數行資料。假設 input.dat 檔內容如下:
The
UNIX
Operation
System
說明: 在命令列上
以選項 -n , 將資料輸出的控制權(參照[section2.5])轉給指令。
利用函數參數 n 將下一行資料(偶數行)取代 pattern space 內的資料行(奇數行)。
利用函數參數 p 將 pattern space 內的資料(偶數行)輸出。
最後 , 整個輸出只有原先檔內的偶數行資料。
sed 命令列如下 :
sed -n -e 'n' -e 'p' infro.dat
執行上述命令後 , 輸出的結果如下 :
UNIX
System
4.13 q
函數參數 q 表示跳離 sed 。其指令格式如下:
[address1] q
對上述格式有下面幾點說明 :
函數參數 q 最多配合一個位址參數。
sed 執行跳離動作時 , 它停止輸入 pattern space 資料 , 同時停止資料送到標準輸出檔。
例 :
題目: 對文件檔執行 script_file 內的編輯指令 , 除非遇到 "Linux" 字串。
說明: 無論 script_file 內是何種指令 , 使用者只要在命令列上用指令/Linux/q , 函數參數 q 會強迫 sed 遇到 "Linux" 時做跳離動作。
sed 命令列如下 :
sed -e '/Linux/q' -f script_file input.dat
4.14 =
函數參數 = 表示印出資料的行數。其指令格式如下:
[address1 ,[address2]] =
對上述格式有下面幾點說明 :
函數參數 = 最多配合兩個位址參數。
執行時 , 行數將在資料輸出前先輸出。
例 :
題目: 印出 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
對上述格式有下面幾點說明 :
函數參數 N 最多配合兩個位址參數。
sed 執行時 , 將下一行資料讀入並添加在 patternspace 內 , 資料行間以換行字元(embeddednewline character)分隔。此外 , 在替換時 , 換行字元可用 n 來 match。
例 :
題目: 將下述兩行資料合。假設 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
對上述格式有下面幾點說明 :
函數參數 D 最多配合兩個位址參數。
函數參數 D 與 d 的比較如下 :
當 pattern space 內只有一資料行時 , D 與 d 作用相同。
當 pattern space 內有多行資料行時
D 表示只刪除 pattern space 內第一行資料 ; d 則全刪除。
D 表示執行刪除後 , pattern space 內不添加下一筆資料 , 而將剩下的資料重新執行 sed script ; d 則讀入下一行後執行 sed script。
例 : 參考 section 3.3 的第二個例子。
4.18 P
函數參數 P 表示印出 pattern space 內的第一行資料。其指令格式如下:
[address1,address2] P
對上述格式有下面幾點說明 :
函數參數 P 最多配合兩個位址參數。
P 與 p , 除了面對的 pattern space 內的資料行數不同外 , 其它均相同。
例(可與[section4.12]中的例):
題目 : 輸出 input.dat 檔內奇數行資料。假設 input.dat 檔內容如下:
The
UNIX
System
說明: 在命令列上以選項 -n , 將資料輸出的控制權(參照[section2.5])轉給指令。
利用函數參數 N 將偶數行添加至 pattern space 內奇數行後。
利用函數參數 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
對上述格式有下面幾點說明 :
函數參數 h 最多配合兩個位址參數。
sed 執行暫存動作時 , 會蓋掉(overwrite) holdspace 內原來的資料。
當 sed 全部執行結束時 , hold space 內資料會自動清除。
例 :參考 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
函數參數 g 最多配合兩個位址參數。
sed 執行放回動作時 , 資料蓋掉(overwrite)(解[13]) pattern space 內原來的資料。
例題 :參考 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" 在同一行:
用指令 s/A/AA/(參照 section4.1)將 "A" 替換成 "AA"。
用指令 b p1 與 :p1 構成圈(loop) , 它目的使上述動作被反覆的執行。每執行一次圈 , 則資料行上的 "A" 就多出一個。例如 , 第一次圈資料行變成 "AA" , 第二次圈資料行變成 "AAA" ...。
用指令 [ABC]/b(解[15]) 來作爲停止圈的條件。當資料行有連續 40 個 A 出現時 , 函數參數 b 將執行的指令跳到最後 , 停止對此行的編輯。
同樣 , 對其它資料行也如同上述的方式執行。
sed 命令列如下 :
sed -e '{
:p1
/A/s/A/AA/
/B/s/B/BB/
/C/s/C/CC/
/[ABC]/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
5.常用的 regular expression
普通字元 由普通字元所組成的 regular expression 其意義與原字串字面意義相同。
^字串 限制字串必須出現於行首 。
$字串 限制字串必須出現行尾。
. 表示任意一字元。
[...] 字元集合, 用以表示兩中括號間所有字元當中的任一個 ,如 [^...]表示兩中括號間所有字元以外的字元。
-& 字元集合中可用"&"指定字元的圍。
* 用以形容其前的字元(或字元集合)可重覆任意多次 。
n 表示嵌入新行字元(imbedded new line character)。
(...) 於 regular expression 中使用"("")"來括住一部份的 regular expression ; 其後可用"1"來表示第一個被"("")"括住的部份。若 regular expression 中使用數次的"(" ")"來括住不同的部份 , 則依次使用"1","2","3",...(最多可到"9")。
另外 , 在不同平臺上 , regularexpression 會有一些不同的限制 , 詳細情況參照 appendix B。
6.解
解一.
就是後面將會提到的 sed script。
解二.
指令 s/Unix/UNIX/ 表示將 "Unix" 替換成 "UNIX"。請參照 section 4.1。
解三.
在指令中有 20 幾個函數參數可供選擇。
解四.
以後這檔案稱作 script file。
解五.
編輯指令 1,10d 中 , 地址參數爲 1,10 , 故 1 至 10 行的資料執行函數參數 d 所指定的刪除動作。
解六.
編輯指令 s/yellow/black/g 中 , 由於沒有地址參數 , 故所有的資料行都要執行函數參數s/yellow/black/g
所指定替換動作。在函數參數 s/yellow/black/g 中 , /yellow/black/g 爲 s 的 argument , 其表示替換資料
行中所有的 "yellow" 成 "black"。
解七.
其命令格式如下 :
sed -n [-e 編輯指令].. [-f script_file].. [文件檔..]
解八.
這些編輯指令中的函數參數可能是 p、l、s 的其中之一。
解九.
在有些情況下 , 也可用編輯指令代替函數參數。例如section3.3 之例二。
解十.
這裏 , sed script 是指 gp.scr 檔的內容。它表示這一次 sed 執行的編輯指令。
解十一.
此函數參數 , 表示替換掉(除掉) pattern space 內兩行間的換行記號。 故 pattern space 內只有一行資料。
解十二.
/pattern/replacement/[flag] 爲函數參數 s 的 argument。
解十三.
注意此時 , 雖然資料是放回 pattern space , 但 hold space 的內容還是不變。
解十四.
注意 ":" 與記號間不可有空格。
解十五.
位址參數 [ABC] , 表示 40 個 A 字母或 40 個 B 字母或 40 個 C 字母。其中 [ABC] 表示 "A" 或 "B"
或 "C"; 其後的 表示其前的字母有 40 個。regular expression 請參照附錄 A