- 論壇徽章:
- 0
|
根據(jù)這壇里的鏈接找到的臺(tái)灣出品的幾篇好貼,感覺(jué)很不錯(cuò),又受到了一次基礎(chǔ)培訓(xùn)和鞏固復(fù)習(xí).所以收藏后也共享給大家,謝謝!
SED 手冊(cè)
中央研究院計(jì)算中心
ASPAC 計(jì)劃
aspac@phi.sinica.edu.tw
技術(shù)報(bào)告: 96005
1996年12月1日
Version:1.0
目錄:
版權(quán)聲明
1. Introduction
何時(shí)使用 sed
何處獲得 sed
sed 能做那些編輯動(dòng)作
sed 如何工作
使用 sed
執(zhí)行命令列上的編輯指令
sed 的編輯指令
地址(address)參數(shù)的表示法
有那些函數(shù)參數(shù)
執(zhí)行檔案內(nèi)的編輯指令
執(zhí)行多個(gè)文件檔的編輯
執(zhí)行輸出的控制
范例
替換文件中的數(shù)據(jù)
搬動(dòng)文件中的數(shù)據(jù)
刪除文件中的數(shù)據(jù)
搜尋文件中的數(shù)據(jù)
介紹函數(shù)參數(shù)
s
d
a
i
c
p
l
r
w
y
!
n
q
=
#
N
D
P
h
H
g
G
x
b
t
附錄 A : 常用的 regular expression
附錄 B : HP-UX Release 9.01 與 SunOS 5.4 內(nèi) sed 對(duì) regular expression 中各種特殊字符的接受能力
參考數(shù)據(jù)
批注
1.Introduction
Sed(Stream EDitor)為 UNIX 系統(tǒng)上提供將編輯工作自動(dòng)化的編輯器 , 使用者無(wú)需直接編輯數(shù)據(jù)。使用者可利用 sed 所提供 20 多種不同的函數(shù)參數(shù) , 組合(批注 [1])它們完成不同的編輯動(dòng)作。此外 , 由于 sed 都以行為單位編輯文件 , 故其亦是行編輯器(line editor)。
一般 sed 最常用在編輯那些需要不斷重復(fù)某些編輯動(dòng)作的檔上 , 例如將文件中的某個(gè)字符串替換成另一個(gè)字符串等等。這些相較于一般 UNIX 編輯器(交談式的, 如 vi、emacs)用手動(dòng)的方式修改檔 , sed 用起來(lái)較省力。下面幾節(jié)將分別介紹:
何時(shí)使用 sed
何處獲得 sed
sed 能做那些編輯動(dòng)作
sed 如何工作
1.1 何時(shí)使用 sed
在修改檔時(shí) , 如果不斷地重復(fù)某些編輯動(dòng)作 , 則可用 sed 自動(dòng)一次執(zhí)行這些編輯動(dòng)作。例如要使 received 文件內(nèi) 1000 封電子信件內(nèi)的發(fā)信人屬名 "Tom" 改成 "John" , 此時(shí)只要在命令列上執(zhí)行一簡(jiǎn)單的 sed 命令就可把檔內(nèi)所有的 "Tom" 字符串替換成 "John"。
再者 , 當(dāng)檔需要許多不同編輯動(dòng)作時(shí) , 則 sed 一次可執(zhí)行那些不同的編輯動(dòng)作。例如 sed 能一次執(zhí)行完將檔中所有空白行刪除、替換字符串、并將使用者輸入的文字添加在文件的第六行等等不同的編輯動(dòng)作。
1.2 何處獲得 sed
一般的 UNIX 系統(tǒng) , 本身即附有 sed。不同的 UNIX 系統(tǒng)所附的 sed 版本亦不盡相同。若讀者所使用的 UNIX 系統(tǒng)上未附有 sed , 則可透過(guò) 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 能做那些編輯動(dòng)作
sed 可刪除(delete)、改變(change)、添加(append)、插入(insert)、合并、交換文件中的數(shù)據(jù)行 , 或讀入其它文件的數(shù)據(jù)到文件中 , 也可替換(substuite)它們其中的字符串、或轉(zhuǎn)換(tranfer)其中的字母等等。例如將檔中的連續(xù)空白行刪成一行、 "local" 字符串替換成 "remote" 、"t" 字母轉(zhuǎn)換成 "T"、將第 10 行數(shù)據(jù)與第 11 數(shù)據(jù)合并等。
1.4 sed 如何工作
如同其它 UNIX 命令 , sed 由標(biāo)準(zhǔn)輸入讀入編輯文件并由標(biāo)準(zhǔn)輸出送出結(jié)果。下圖表示 sed 將資料行 "Unix" 替換成 "UNIX" ,
在圖中 , 上方 standard input 為標(biāo)準(zhǔn)輸入 , 是讀取數(shù)據(jù)之處 ; standard output 為標(biāo)準(zhǔn)輸出 , 是送出結(jié)果之處 ; 中間 sed 方塊的下面兩個(gè)虛線方塊表示 sed 的工作流程。其中 , 左邊虛線方塊表示 sed 將標(biāo)準(zhǔn)輸入數(shù)據(jù)置入 pattern space , 右邊虛線方塊表示 sed 將 pattern space 中編輯完畢后的數(shù)據(jù)送到標(biāo)準(zhǔn)輸出。
在虛線方塊中 , 兩個(gè)實(shí)線方塊分別表示 pattern space 與 sed script。其中 , pattern space 為一緩沖區(qū) , 它是 sed 工作場(chǎng)所 ; 而 sed script 則表示一組執(zhí)行的編輯指令。
在圖中, 左邊虛線方塊 "Unix" 由標(biāo)準(zhǔn)輸入置入 pattern space ; 接著 , 在右邊虛線方塊中 , sed 執(zhí)行 sed script 中的編輯指令 s/Unix/UNIX/ (批注 [2]) , 結(jié)果 "Unix" 被替換成 "UNIX" , 之后 , "UNIX" 由 pattern space 送到標(biāo)準(zhǔn)輸出。
總合上述所言 , 當(dāng) sed 由標(biāo)準(zhǔn)輸入讀入一行數(shù)據(jù)并放入 pattern space 時(shí) , sed 依照 sed script 的編輯指令逐一對(duì) pattern space 內(nèi)的數(shù)據(jù)執(zhí)行編輯 , 之后 , 再由 pattern space 內(nèi)的結(jié)果送到標(biāo)準(zhǔn)輸出 , 接著再將下一行數(shù)據(jù)讀入。如此重復(fù)執(zhí)行上述動(dòng)作 , 直至讀完所有數(shù)據(jù)行為止。
使用 sed
Sed 命令列可分成編輯指令與文件文件部份。其中 , 編輯指令負(fù)責(zé)控制所有的編輯工作 ; 檔檔表示所處理的檔案。sed 的編輯指令均由位址(address)與函數(shù)(function)兩部份組成 , 其中 , 在執(zhí)行時(shí) , sed 利用它的地址參數(shù)來(lái)決定編輯的對(duì)象;而用它的函數(shù)參數(shù)(批注[3])編輯。
此外 , sed 編輯指令 , 除了可在命令列上執(zhí)行 , 也可在檔案內(nèi)執(zhí)行。其中差別只是在命令列上執(zhí)行時(shí) , 其前必須加上選項(xiàng) -e ; 而在檔案(批注[4])內(nèi)時(shí) , 則只需在其文件名前加上選項(xiàng) -f。另外 , sed 執(zhí)行編輯指令是依照它們?cè)诿盍猩匣驒n內(nèi)的次序。
下面各節(jié) , 將介紹執(zhí)行命令列上的編輯指令 、sed 編輯指令、執(zhí)行檔案內(nèi)的編輯指令、執(zhí)行多個(gè)檔案的編輯、及執(zhí)行 sed 輸出控制。
2.1 執(zhí)行命令列上的編輯指令
2.2 sed 編輯指令
2.3 執(zhí)行檔案內(nèi)的編輯指令
2.4 執(zhí)行多個(gè)檔案的編輯
2.5 執(zhí)行 sed 輸出控制
2.1.執(zhí)行命令列上的編輯指令
當(dāng)編輯指令(參照[section 2.2])在命令列上執(zhí)行時(shí) , 其前必須加上選項(xiàng) -e 。其命令格式如下 :
sed -e '編輯指令1' -e '編輯指令2' ... 文件檔
其中 , 所有編輯指令都緊接在選項(xiàng) -e 之后 , 并置于兩個(gè) " ' " 特殊字符間。另外 , 命令上編輯指令的執(zhí)行是由左而右。
一般編輯指令不多時(shí) , 使用者通常直接在命令上執(zhí)行它們。例如 , 刪除 yel.dat 內(nèi) 1 至 10 行數(shù)據(jù) , 并將其余文字中的 "yellow" 字符串改成 "black" 字符串。此時(shí) , 可將編輯指令直接在命令上執(zhí)行 , 其命令如下 :
sed -e '1,10d' -e 's/yellow/black/g' yel.dat
在命令中 , 編輯指令 '1,10d'(批注[5])執(zhí)行刪除 1 至 10 行數(shù)據(jù) ; 編輯指令 's/yellow/black/g'(批注[6]) , "yellow" 字符串替換(substuite)成 "black" 字符串。
2.2 sed 的編輯指令
sed 編輯指令的格式如下 :
[address1[,address2]]function[argument]
其中 , 地址參數(shù) address1 、address2 為行數(shù)或 regular expression 字符串 , 表示所執(zhí)行編輯的數(shù)據(jù)行 ; 函數(shù)參數(shù) function[argument] 為 sed 的內(nèi)定函數(shù) , 表示執(zhí)行的編輯動(dòng)作。
下面兩小節(jié) , 將仔細(xì)介紹地址參數(shù)的表示法與有哪些函數(shù)參數(shù)供選擇。
2.2.1 地址(address)參數(shù)的表示法
實(shí)際上 , 地址參數(shù)表示法只是將要編輯的數(shù)據(jù)行 , 用它們的行數(shù)或其中的字符串來(lái)代替表示它們。下面舉幾個(gè)例子說(shuō)明(指令都以函數(shù)參數(shù) d(參照[section4.2]) 為例) :
刪除文件內(nèi)第 10 行數(shù)據(jù) , 則指令為 10d。
刪除含有 "man" 字符串的數(shù)據(jù)行時(shí) , 則指令為 /man/d。
刪除檔內(nèi)第 10 行到第 200 行數(shù)據(jù), 則指令為 10,200d。
刪除檔內(nèi)第 10 行到含 "man" 字符串的數(shù)據(jù)行 , 則指令為 10,/man/d。
接下來(lái) , 以地址參數(shù)的內(nèi)容與其個(gè)數(shù)兩點(diǎn) , 完整說(shuō)明指令中位址參數(shù)的表示法(同樣也以函數(shù)參數(shù) d 為例)。
地址參數(shù)的內(nèi)容:
地址為十進(jìn)制數(shù) : 此數(shù)字表示行數(shù)。當(dāng)指令執(zhí)行時(shí) , 將對(duì)符合此行數(shù)的數(shù)據(jù)執(zhí)行函數(shù)參數(shù)指示的編輯動(dòng)作。例如 , 刪除數(shù)據(jù)文件中的第 15 行數(shù)據(jù) , 則指令為 15d(參照[section4.2])。其余類(lèi)推 ,如刪除數(shù)據(jù)文件中的第 m 行數(shù)據(jù) , 則指令為 md 。
地址為 regular expression(參照[附錄 A]):
當(dāng)數(shù)據(jù)行中有符合 regular expression 所表示的字符串時(shí) , 則執(zhí)行函數(shù)參數(shù)指示的編輯動(dòng)作。另外 , 在 regular expression 前后必須加上 "/"。例如指令為 /t.*t/d , 表示刪除所有含兩 "t" 字母的數(shù)據(jù)行。其中 , "." 表示任意字符; "*" 表示其前字符可重復(fù)任意次 , 它們結(jié)合 ".*" 表示兩 "t" 字母間的任意字符串。
地址參數(shù)的個(gè)數(shù) : 在指令中 , 當(dāng)沒(méi)有地址參數(shù)時(shí) , 表示全部數(shù)據(jù)行執(zhí)行函數(shù)參數(shù)所指示的編輯動(dòng)作; 當(dāng)只有一地址參數(shù)時(shí) , 表示只有符合地址的數(shù)據(jù)行才編輯 ; 當(dāng)有兩個(gè)地址參數(shù) , 如 address1,address2 時(shí) , 表示對(duì)數(shù)據(jù)區(qū)執(zhí)行編輯 , address1 代表起始數(shù)據(jù)行 , address2 代表結(jié)束資料行。對(duì)于上述內(nèi)容 , 以下面例子做具體說(shuō)明。
例如指令為
d
其表示刪除文件內(nèi)所有數(shù)據(jù)行。
例如指令為
5d
其表示刪除文件內(nèi)第五行資料。
例如指令為
1,/apple/d
其表示刪除資料區(qū) , 由檔內(nèi)第一行至內(nèi)有 "apple" 字符串的數(shù)據(jù)行。
例如指令為
/apple/,/orange/d
其表示刪除資料區(qū) , 由檔內(nèi)含有 "apple" 字符串至含有 "orange" 字符串的數(shù)據(jù)行
2.2.2 有那些函數(shù)(function)參數(shù)
下頁(yè)表仲介紹所有 sed 的函數(shù)參數(shù)(參照[chapter 4])的功能。
函數(shù)參數(shù) 功能
: label 建立 script file 內(nèi)指令互相參考的位置。
# 建立批注
{ } 集合有相同位址參數(shù)的指令。
! 不執(zhí)行函數(shù)參數(shù)。
= 印出資料行數(shù)( line number )。
a\ 添加使用者輸入的數(shù)據(jù)。
b label 將執(zhí)行的指令跳至由 : 建立的參考位置。
c\ 以使用者輸入的數(shù)據(jù)取代數(shù)據(jù)。
d 刪除數(shù)據(jù)。
D 刪除 pattern space 內(nèi)第一個(gè) newline 字母 \ 前的數(shù)據(jù)。
g 拷貝數(shù)據(jù)從 hold space。
G 添加資料從 hold space 至 pattern space 。
h 拷貝數(shù)據(jù)從 pattern space 至 hold space 。
H 添加資料從 pattern space 至 hold space 。
l 印出 l 資料中的 nonprinting character 用 ASCII 碼。
i\ 插入添加使用者輸入的數(shù)據(jù)行。
n 讀入下一筆資料。
N 添加下一筆資料到 pattern space。
p 印出資料。
P 印出 pattern space 內(nèi)第一個(gè) newline 字母 \ 前的數(shù)據(jù)。
q 跳出 sed 編輯。
r 讀入它檔內(nèi)容。
s 替換字符串。
t label 先執(zhí)行一替換的編輯指令 , 如果替換成牛p>則將編輯指令跳至 : label 處執(zhí)行。
w 寫(xiě)資料到它文件內(nèi)。
x 交換 hold space 與 pattern space 內(nèi)容。
y 轉(zhuǎn)換(transform)字符。
雖然 , sed 只有上表所述幾個(gè)擁有基本編輯功能的函數(shù) , 但由指令中位址參數(shù)和指令與指令間的配合 , 也能使 sed 完成大部份的編輯任務(wù)。
2.3 執(zhí)行檔案內(nèi)的編輯指令
當(dāng)執(zhí)行的指令太多 , 在命令列上撰寫(xiě)起來(lái)十分混亂 , 此時(shí) , 可將這些指令整理儲(chǔ)存在檔案(譬如檔名為 script_file )內(nèi) , 用選項(xiàng) -f script_file , 則讓 sed 執(zhí)行 script_file 內(nèi)的編輯指令。其命令的格示如下 :
sed -f script_file 文件檔
其中 , 執(zhí)行 script_file 內(nèi)編輯指令的順序是由上而下。例如上一節(jié)的例子 , 其可改成如下命令:
sed -f ysb.scr yel.dat
其中 , ysb.scr 檔的內(nèi)容如下 :
1,10d
s/yellow/black/g
另外 , 在命令列上可混合使用選項(xiàng) -e 與 -f , sed 執(zhí)行指令順序依然是由命令列的左到右, 如執(zhí)行至 -f 后檔案內(nèi)的指令 , 則由上而下執(zhí)行。
2.4 執(zhí)行多個(gè)文件檔的編輯
在 sed 命令列上 , 一次可執(zhí)行編輯多個(gè)檔檔 , 它們跟在編輯指令之后。例如 , 替換 white.dat、red.dat、black.dat 文件內(nèi)的 "yellow" 字符串成 "blue" , 其命令如下:
sed -e 's/yellow/blue/g' white.dat red.dat black.dat
上述命令執(zhí)行時(shí) , sed 依 white.dat、red.dat、black.dat 順序 , 執(zhí)行編輯指令 s/yellow/blue/(請(qǐng)參照[section 4.1] , 進(jìn)行字符串的替換。
2.5.執(zhí)行輸出的控制
在命令列上的選項(xiàng) -n (批注[7]) 表示輸出由編輯指令控制。由前章內(nèi)容得知 , sed 會(huì) "自動(dòng)的" 將數(shù)據(jù)由 pattern space 輸送到標(biāo)準(zhǔn)輸出檔。但借著選項(xiàng) -n , 可將 sed 這 "自動(dòng)的" 的動(dòng)作改成 "被動(dòng)的" 由它所執(zhí)行的編輯指令(批注[8])來(lái)決定結(jié)果是否輸出。
由上述可知 , 選項(xiàng) -n 必須與編輯指令一起配合 , 否則無(wú)法獲得結(jié)果。例如 , 印出 white.dat 文件內(nèi)含有 "white" 字符串的數(shù)據(jù)行 , 其命令如下:
sed -n -e '/white/p' white.dat
上面命令中 , 選項(xiàng) -n 與編輯指令 /white/p (參照[section4.6]) 一起配合控制輸出。其中 , 選項(xiàng) -n 將輸出控制權(quán)移給編輯指令;/white/p 將數(shù)據(jù)行中含有 "white" 字符串印出屏幕。
3.范例
一般在實(shí)際使用編輯器的過(guò)程中 , 常需要執(zhí)行替換文件中的字符串、搬移、刪除、與搜尋數(shù)據(jù)行等等動(dòng)作。當(dāng)然 , 一般交談式編輯器(如 vi、emacs)都能做得到上述功能 , 但文件一旦有大量上述編輯需求時(shí) , 則用它們編輯十分沒(méi)有效率。本章將用舉例的方式說(shuō)明如何用 sed 自動(dòng)執(zhí)行這些編輯功能。此外 , 在本章范例中 , 均以下述方式描述檔的需求 :
將文件中...數(shù)據(jù) , 執(zhí)行...(動(dòng)作)
如此 , 目的是為了能將它們迅速的轉(zhuǎn)成編輯指令。其中 , " ...數(shù)據(jù)" 部份 , 轉(zhuǎn)成指令中的位址參數(shù)表示 ; "執(zhí)行...動(dòng)作" 部份 , 則轉(zhuǎn)成函數(shù)參數(shù)表示 。另外 , 當(dāng) "執(zhí)行...動(dòng)作" 要由數(shù)個(gè)函數(shù)參數(shù)表示時(shí) , 則可利用 "{ "與 " }" 集合這些函數(shù)參數(shù)(批注[9]) , 其指令形式如下 :
地址參數(shù){
函數(shù)參數(shù)1
函數(shù)參數(shù)2
函數(shù)參數(shù)3
.
:
}
上述指令表示 , 將對(duì)符合地址參數(shù)的數(shù)據(jù) , 依次執(zhí)行函數(shù)參數(shù)1、函數(shù)參數(shù)2、函數(shù)參數(shù)3 ... 表示的動(dòng)作。下面各節(jié) , 分別舉例說(shuō)明 sed 替換數(shù)據(jù)、移動(dòng)、刪除數(shù)據(jù)、及搜尋數(shù)據(jù)的命令。
3.1 替換文件中的數(shù)據(jù)
3.2 搬動(dòng)文件中的數(shù)據(jù)
3.3 刪除文件中的數(shù)據(jù)
3.4 搜尋文件中的數(shù)據(jù)
3.1 替換文件中的數(shù)據(jù)
Sed 可替換文件中的字符串、數(shù)據(jù)行、甚至數(shù)據(jù)區(qū)。其中 , 表示替換字符串的指令中的函數(shù)參數(shù)為 s(參照[section4.1]); 表示替換數(shù)據(jù)行、或數(shù)據(jù)區(qū)的指令中的函數(shù)參數(shù)為 c(參照[section4.5])。上述情況以下面三個(gè)例子說(shuō)明。上述情況以下面三個(gè)例子說(shuō)明。
例一. 將文件中含 "machine" 字符串的數(shù)據(jù)行中的 "phi" 字符串 , 替換成為 "beta" 字符串。其命令列如下 :
sed -e '/machine/s/phi/beta/g' input.dat(以后文件檔都以 input.dat 代表)
例二. 將文件中第 5 行數(shù)據(jù) , 替換成句子 "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 行的資料區(qū) , 替換成如下兩行資料 :
How are you?
data be deleted!
則其命令列如下
sed -e '1,100c\
How are you?\
data be deleted!
' input.dat
3.2 搬動(dòng)文件中的數(shù)據(jù)
使用者可用 sed 中的 hold space 暫存編輯中的數(shù)據(jù)、用函數(shù)參數(shù) w(參照[section4.9])將文件數(shù)據(jù)搬動(dòng)到它文件內(nèi)儲(chǔ)存、或用函數(shù)參數(shù) r(參照[section4.8])將它檔內(nèi)容搬到文件內(nèi)。Hold space 是 sed 用來(lái)暫存 pattern space 內(nèi)數(shù)據(jù)的緩存器 , 當(dāng) sed 執(zhí)行函數(shù)參數(shù) h、H(參照[section4.19])時(shí) , 會(huì)將 pattern space 資料暫存到 hold space;當(dāng)執(zhí)行函數(shù)參數(shù) x、g、G(參照[section4.22])時(shí) , 會(huì)將暫存的資料取到 pattern space 。下面舉三個(gè)例子說(shuō)明。
例一. 將文件中的前 100 數(shù)據(jù) , 搬到文件中第 300 后輸出。其命令列如下 :
sed -f mov.scr 文件檔
mov.scr 檔的內(nèi)容為
1,100{
H
d
}
300G
其中 ,
1,100{
H
d
}
它表示將文件中的前 100 數(shù)據(jù) , 先儲(chǔ)存(參照[section4.19])在 hold space 之后刪除 ;指令 300G (參照[section4.22]) 表示 , 將 hold space 內(nèi)的資料 , 添加在文件中的第 300 數(shù)據(jù)后輸出。
例二. 將文件中含 "phi" 字符串的數(shù)據(jù)行 , 搬至 mach.inf 檔中儲(chǔ)存。其命令列如下 :
sed -e '/phi/w mach.inf' 文件檔
例三. 將 mach.inf 檔內(nèi)容 , 搬至文件中含 "beta" 字符串的數(shù)據(jù)行。其命令列如下 :
sed -e '/beta/r mach.inf' 文件檔
另外 , 由于 sed 是一 stream(參照[section1.4])編輯器 , 故理論上輸出后的文件數(shù)據(jù)不可能再搬回來(lái)編輯。
3.3 刪除文件中的數(shù)據(jù)
因?yàn)?sed 是一行編輯器 , 所以 sed 很容易刪除個(gè)別數(shù)據(jù)行或整個(gè)數(shù)據(jù)區(qū)。一般用函數(shù)參數(shù) d(參照[section4.2])或 D(參照[section4.17]) 來(lái)表示。下面舉兩個(gè)例子說(shuō)明。
將檔內(nèi)所有空白行全部刪除。其命令列為
sed -e '/^$/d' 文件檔
regular expression(批注[附錄 A]) , ^$ 表示空白行。 其中 , ^ 限制其后字符串必須在行首; $ 限制其前字符串必須在行尾。
將文件內(nèi)連續(xù)的空白行 , 刪除它們成為一行。其命令列為
sed -e '/^$/{
N
/^$/D
}' 文件檔
其中 , 函數(shù)參數(shù) N(參照[section4.16])表示 , 將空白行的下一行資料添加至 pattern space 內(nèi)。函數(shù)參數(shù) /^$/D 表示 , 當(dāng)添加的是空白行時(shí) , 刪除第一行空白行 , 而且剩下的空白行則再重新執(zhí)行指令一次。指令重新執(zhí)行一次 , 刪除一行空白行 , 如此反復(fù)直至空白行后添加的為非空白行為止 , 故連續(xù)的空白行最后只剩一空白行被輸出。
3.4 搜尋文件中的數(shù)據(jù)
Sed 可以執(zhí)行類(lèi)似 UNIX 命令 grep 的功能。理論上 , 可用 regular expression(參照[附錄 A])。例如 , 將檔中含有 "gamma" 字符串的數(shù)據(jù)行輸出。則其命令列如下:
sed -n -e '/gamma/p' 文件檔
但是 , sed 是行編輯器 , 它的搜尋基本上是以一行為單位。因此 , 當(dāng)一些字符串因換行而被拆成兩部份時(shí) , 一般的方法即不可行。此時(shí) , 就必須以合并兩行的方式來(lái)搜尋這些數(shù)據(jù)。其情況如下面例子:
例. 將文件中含 "omega" 字符串的數(shù)據(jù)輸出。其命令列如下
sed -f gp.scr 文件檔
gp.scr 檔的內(nèi)容如下 :
/omega/b
N
h
s/.*\n//
/omega/b
g
D
在上述 sed script(批注[10]), 因借著函數(shù)參數(shù) b 形成類(lèi)似 C 語(yǔ)言中的 case statement 結(jié)構(gòu) , 使得 sed 可分別處理當(dāng)數(shù)據(jù)內(nèi)含 "omega" 字符串 ; 當(dāng) "omega" 字符串被拆成兩行 ; 以及數(shù)據(jù)內(nèi)沒(méi)有"omega" 字符串的情況。接下來(lái)就依上述的三種情況 , 將 sed script 分成下面三部份來(lái)討論。
當(dāng)數(shù)據(jù)內(nèi)含 "omega" , 則執(zhí)行編輯指令
/omega/b
它表示當(dāng)資料內(nèi)含 "omega" 字符串時(shí) , sed 不用再對(duì)它執(zhí)行后面的指令 , 而直接將它輸出。
當(dāng)數(shù)據(jù)內(nèi)沒(méi)有"omega" , 則執(zhí)行編輯指令如下
N
h
s/.*\n//
/omega/b
其中 , 函數(shù)參數(shù) N(參照[section 4.16]) , 它表示將下一行資料讀入使得 pattern space 內(nèi)含前后兩行數(shù)據(jù) 。函數(shù)參數(shù) h(參照[section 4.19]) , 它表示將 pattern space 內(nèi)的前后兩行資料存入 hold space 。函數(shù)參數(shù) s/.*\n// , 它表示將 pattern space 內(nèi)的前后兩行資料合并(批注[11])成一行。/omega/b , 它表示如果合并后的數(shù)據(jù)內(nèi)含 "omega" 字符串 , 則不用再執(zhí)行它之后的指令 , 而將此數(shù)據(jù)自動(dòng)輸出 ;
當(dāng)合并后的數(shù)據(jù)依舊不含 "omega" , 則執(zhí)行編輯指令如下
g
D
其中 , 函數(shù)參數(shù) g(參照[section4.21]) , 它表示將 hold space 內(nèi)合并前的兩行資料放回 pattern space。 函數(shù)參數(shù) D(參照[section4.17]) , 它表示刪除兩行資料中的第一行資料 , 并讓剩下的那行數(shù)據(jù) , 重新執(zhí)行 sed script。如此 , 無(wú)論的資料行內(nèi)或行間的字符串才可搜尋完全。
介紹函數(shù)參數(shù)
本章將以一節(jié)一個(gè)函數(shù)參數(shù)的方式 ,介紹所有 sed 提供的函數(shù)參數(shù) , 其中有
| s | d | a | i | c | p | l | r | w | y | ! | n | q | = | # | N | D | P | h | H | g | G | x | b | t |
另外 , 在各節(jié)中 , 首先簡(jiǎn)單介紹函數(shù)參數(shù)功能 , 接著說(shuō)明函數(shù)參數(shù)與地址參數(shù)配合的格式 , 而其中也一并描述 sed 執(zhí)行此函數(shù)參數(shù)的工作情形。
4.1 s
函數(shù)參數(shù) s 表示替換(substitute)文件內(nèi)字符串。其指令格式如下 :
[address1[ ,address2]] s/pattern/replacemen/[flag]
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) s 最多與兩個(gè)地址參數(shù)配合。
關(guān)于 "s/pattern/replacement/[flag]"(批注[12]) 有下面幾點(diǎn)說(shuō)明:
pattern : 它為 reguler expression 字符串。它表示文件中要被替換的字符串。
replacement : 它為一般字符串。但其內(nèi)出現(xiàn)下列字符有特別意義 :
& : 代表其前 pattern 字符串。例如
sed -e 's/test/& my car/' 資料文件名
指令中 , & 代表 pattern 字符串 "test"。故執(zhí)行后 , 數(shù)據(jù)文件的 "test" 被替換成 "test my car"。
\n : 代表 pattern 中被第 n 個(gè) \( 、\)(參照[附錄 A]) 所括起來(lái)的字符串。例如
sed -e 's/\(test\) \(my\) \(car\)/[\2 \3 \1]/' 資料文件名
指令中 , \1 表示 "test"、\2 表示 "my"、\1 表示 "car" 字符串。故執(zhí)行后 , 數(shù)據(jù)文件的 "test my car" 被替換成 "[my car test]"。
\ : 可用它來(lái)還原一些特殊符號(hào)(如上述的 & 與 \ )本身字面上的意義 , 或用它來(lái)代表?yè)Q行。
flag : 主要用它來(lái)控制一些替換情況 :
當(dāng) flag 為 g 時(shí) , 代表替換所有符合(match)的字符串 。
當(dāng) flag 為十進(jìn)制數(shù) m 時(shí) , 代表替換行內(nèi)第 m 個(gè)符合的字符串。
當(dāng) flag 為 p 時(shí) , 代表替換第一個(gè)符合 pattern 的字符串后 , 將數(shù)據(jù)輸出標(biāo)準(zhǔn)輸出文件。
當(dāng) flag 為 w wfile 時(shí) , 代表替換第一個(gè)符合 pattern 的字符串后 , 輸出到 wfile 檔內(nèi)(如果 wfile 不存在 , 則會(huì)重新開(kāi)啟名為 wfile 的檔案)。
當(dāng)沒(méi)有 flag 時(shí) , 則將資料行內(nèi)第一個(gè)符合 pattern 的字符串以 replacement 字符串來(lái)替換 。
delimiter : 在 "/pattern/replace/[flag] " 中 "/" 被當(dāng)成一 delimiter。除了空白(blank)、換行(newline) 之外 , 使用者可用任何字符作為 delimiter。例如下述編輯指令
s#/usr#/usr1#g
上述命令中 \verb|#| 為 delimiter。如果用 "/" 做 delimiter , 則 sed 會(huì)將 pattern 與 replacement 中的 "/" 當(dāng)成 delimiter 而發(fā)生錯(cuò)誤。
范例:
題目 : 替換 input.dat 檔(后面如果沒(méi)有特別指定 , 均假設(shè)檔檔名為 input.dat)內(nèi) "1996" 字符串成 "1997" , 同時(shí)將這些數(shù)據(jù)行存入 year97.dat 檔內(nèi)。
說(shuō)明 : 用函數(shù)參數(shù) s 指示 sed 將 "1996" 字符串替換成 "1997" , 另外用 s argument 中的 flag w 指示 sed 將替換過(guò)的資料行存入 year97.dat 檔內(nèi)。
sed 命令列:
sed -e 's/1996/1997/w year97.dat' input.dat
4.2 d
函數(shù)參數(shù) d 表示刪除數(shù)據(jù)行 , 其指令格式如下:
[address1[ ,address2]] d
對(duì)上述格式有下面幾點(diǎn)說(shuō)明:
函數(shù)參數(shù) d 最多與兩個(gè)地址參數(shù)配合。
sed 執(zhí)行刪除動(dòng)作情況如下 :
將 pattern space 內(nèi)符合地址參數(shù)的數(shù)據(jù)刪除。
將下一筆資料讀進(jìn) pattern space 。
重新執(zhí)行 sed script。
范例 : 可參考 section 3.3。
4.3 a
函數(shù)參數(shù) a 表示將資料添加到文件中。其指令格式如下:
[address1] a\ 使用者所輸入的數(shù)據(jù)
對(duì)上述格式有下面幾點(diǎn)說(shuō)明:
函數(shù)參數(shù) a 最多與一個(gè)地址參數(shù)配合。
函數(shù)參數(shù) a 緊接著 "\" 字符用來(lái)表示此行結(jié)束 , 使用者所輸入的數(shù)據(jù)必須從下一行輸入。如果數(shù)據(jù)超過(guò)一行 , 則須在每行的結(jié)尾加入"\"。
sed 執(zhí)行添加動(dòng)作情況如下 : 當(dāng) pattern space 內(nèi)數(shù)據(jù)輸出后 , sed 跟著輸出使用者所輸入的數(shù)據(jù)。
范例 :
題目: 添加 "多任務(wù)操作系統(tǒng)" 在含 "UNIX" 字符串的數(shù)據(jù)行后。假設(shè) input.dat 檔的內(nèi)容如下 :
UNIX
說(shuō)明: 用函數(shù)參數(shù) a 將所輸入的數(shù)據(jù)添加在含 "UNIX" 字符串的數(shù)據(jù)行后。
sed 命令列如下 :
sed -e '/UNIX/a\
多任務(wù)操作系統(tǒng)
' input.dat
執(zhí)行上述命令后 , 其輸出結(jié)果如下 :
UNIX
多任務(wù)操作系統(tǒng)
4.4 i
函數(shù)參數(shù) i 表示將資料插入文件中。其指令格式如下:
[address1] i\ 使用者所輸入的數(shù)據(jù)
對(duì)上述格式有下面幾點(diǎn)說(shuō)明:
函數(shù)參數(shù) i 最多與一個(gè)地址參數(shù)配合。
函數(shù)參數(shù) i 緊接著 "\" 字符用來(lái)表示此行結(jié)束 , 使用者所輸入的數(shù)據(jù)必須從下一行輸入。如果數(shù)據(jù)超過(guò)一行 , 則須在每行的結(jié)尾加入"\"。
sed 執(zhí)行插入動(dòng)作的情況如下 : 在 pattern space 內(nèi)數(shù)據(jù)輸出前 , sed 先輸出使用者所輸入的數(shù)據(jù)。
范例 :
題目: 將 "文章版權(quán)屬于中央研究院" 插在 input.dat 檔中含 "院長(zhǎng) : 李遠(yuǎn)哲" 的數(shù)據(jù)行之前。假設(shè) input.dat 檔內(nèi)容如下 :
院長(zhǎng) : 李遠(yuǎn)哲
說(shuō)明: 用函數(shù)參數(shù) i 將數(shù)據(jù)行 "文章版權(quán)屬于中央研究院" 插在含 "院長(zhǎng) : 李遠(yuǎn)哲" 的數(shù)據(jù)行之前。
sed 命令列如下:
sed -e '/院長(zhǎng) : 李遠(yuǎn)哲/i\
文章版權(quán)屬于中央研究院
' input.dat
執(zhí)行上述命令后的輸出如下 :
文章版權(quán)屬于中央研究院
院長(zhǎng) : 李遠(yuǎn)哲
4.5 c
函數(shù)參數(shù) c 表示改變文件中的數(shù)據(jù)。其格式如下:
[address1[ ,address2]]c\ 使用者所輸入的數(shù)據(jù)
對(duì)上述格式有下面幾點(diǎn)說(shuō)明:
函數(shù)參數(shù) c 最多與兩個(gè)地址參數(shù)配合。
函數(shù)參數(shù) c 緊接著 "\" 字符用來(lái)表示此行結(jié)束 , 使用者所輸入的數(shù)據(jù)必須從下一行輸入。如果數(shù)據(jù)超過(guò)一行 , 則須在每行的結(jié)尾加入"\"。
sed 執(zhí)行改變動(dòng)作的情況 : 在 pattern space 內(nèi)數(shù)據(jù)輸出時(shí) , sed 改變它成為使用者所輸入的數(shù)據(jù)。
范例 : 參考 section 3.1 之例二、三。
4.6 p
函數(shù)參數(shù) p 表示印出資料。其指令格式如下 :
[address1[ , address2]] p
對(duì)于上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) p 最多與兩個(gè)地址參數(shù)配合。
sed 執(zhí)行印出動(dòng)作的情況如下 : sed 拷備一份 pattern space 內(nèi)容至標(biāo)準(zhǔn)輸出檔。
范例 : 參考 section 3.4 開(kāi)頭的內(nèi)容。
4.7 l
函數(shù)參數(shù) l , 除可將資料中的 nonprinting character 以 ASCII碼列出外 , 其于均與函數(shù)參數(shù) p 相同。例如 , 將下面 input.dat 檔中的 ^[ 以 ASCII 碼印出
The Great ^[ is a movie starring Steve McQueen.
執(zhí)行命令 sed -e 'l' input.dat 后 , 則輸出結(jié)果如下 :
The Great \003 is a movie starring Steve McQueen.
The Great is a movie starring Steve McQueen.
上述第二行數(shù)據(jù)為 sed 的自動(dòng)輸出(請(qǐng)參照批注[]。
4.8 r
函數(shù)參數(shù) r 表示讀入它檔案內(nèi)容到檔中。其指令格式如下 :
[address1] r 它檔名稱(chēng)
對(duì)于上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) r 最多與一個(gè)地址參數(shù)配合。
在指令中 , 函數(shù)參數(shù) r 與它檔名稱(chēng)間 , 只能有一空格。
sed 執(zhí)行讀入動(dòng)作的情況如下 : 在 pattern space 內(nèi)數(shù)據(jù)輸出后 , sed 讀出它檔的內(nèi)容跟著輸出。當(dāng)它檔不存在時(shí) , sed 照樣執(zhí)行其它指令而不會(huì)有任何錯(cuò)誤訊息產(chǎn)生。
范例 : 參考 section 3.1 之例三。
4.9 w
函數(shù)參數(shù) w 表示將檔中的寫(xiě)到它檔內(nèi)。其指令格式如下 :
[address1[ ,address2]] w 它檔名稱(chēng)
對(duì)于上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) w 最多與兩個(gè)地址參數(shù)配合。
在指令中 , 函數(shù)參數(shù) w 與它檔名稱(chēng)間 , 只能有一空格。
sed 執(zhí)行寫(xiě)出動(dòng)作的情況如 : 將 pattern space 內(nèi)資料寫(xiě)到它文件內(nèi)。數(shù)據(jù)寫(xiě)入時(shí) , 會(huì)取代(overwrite)原來(lái)檔案內(nèi)的數(shù)據(jù)。另外 , 當(dāng)它檔不存在時(shí) , sed 會(huì)重新產(chǎn)生(creat)它。
范例:參考 section 3.1 之例二。
4.10 y
函數(shù)參數(shù) y 表示轉(zhuǎn)換數(shù)據(jù)中的字符。其指令格式如下 :
[address1[ ,address2]]y /xyz.../abc.../
對(duì)于上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù)最多配合兩個(gè)地址參數(shù)。
指令中 , /abc.../xyz.../(x、y、z、a、b、c 代表某些字符) 為 y 的 argument 。其中 abc... 與 xyz... 的字符個(gè)數(shù)必須相同。
sed 執(zhí)行轉(zhuǎn)換時(shí) , 將 pattern space 內(nèi)數(shù)據(jù)內(nèi)的 a 字符轉(zhuǎn)換成 x 字符 、b 字符轉(zhuǎn)換成 y 字符 、c 字符轉(zhuǎn)換成 z 字符 ...。
范例:
題目: 將 input.dat 文件中的小寫(xiě)字母改成大寫(xiě)。假設(shè) input.dat 檔的內(nèi)容如下 :
Sodd's Second Law:
Sooner or later, the worst possible set of
circumstances is bound to occur.
說(shuō)明:利用函數(shù)參數(shù) y 指示 sed 做字母大小的轉(zhuǎn)換。
sed 命令列如下 :
sed -e '
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
' input.dat
執(zhí)行上述命令輸出結(jié)果如下 :
SODD'S SECOND LAW:
SOONER OR LATER, THE WORST POSSIBLE SET OF
CIRCUMSTANCES IS BOUND TO OCCUR.
4.11 !
函數(shù)參數(shù) ! 表示不執(zhí)行函數(shù)參數(shù)。當(dāng)有如下指令時(shí) ,
[address1[ , address2]] ! 函數(shù)參數(shù)
表示 , 對(duì)符合地址參數(shù)之?dāng)?shù)據(jù)不執(zhí)行函數(shù)參數(shù)。例如刪除 , 除了含 "1996" 字符串 , 所有數(shù)據(jù)行 , 則執(zhí)行如下命令
sed -e '/1996/!d' input.dat
4.12 n
函數(shù)參數(shù) n 表示讀入下一行資料。其指令格式如下:
[address1[ ,address2]] n
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) n 最多配合兩個(gè)地址參數(shù)。
sed 執(zhí)行讀入下一行動(dòng)作的情況如下 :
輸出在 pattern space 的數(shù)據(jù)。
將下一筆資料讀到 pattern space。
執(zhí)行下一個(gè)編輯指令。
范例(可與[section4.18]中的范例比較):
題目 : 輸出 input.dat 文件內(nèi)偶數(shù)行資料。假設(shè) input.dat 檔內(nèi)容如下:
The
UNIX
Operation
System
說(shuō)明: 在命令列上
以選項(xiàng) -n , 將數(shù)據(jù)輸出的控制權(quán)(參照[section2.5])轉(zhuǎn)給指令。
利用函數(shù)參數(shù) n 將下一行數(shù)據(jù)(偶數(shù)行)取代 pattern space 內(nèi)的資料行(奇數(shù)行)。
利用函數(shù)參數(shù) p 將 pattern space 內(nèi)的數(shù)據(jù)(偶數(shù)行)輸出。
最后 , 整個(gè)輸出只有原先文件內(nèi)的偶數(shù)行數(shù)據(jù)。
sed 命令列如下 :
sed -n -e 'n' -e 'p' infro.dat
執(zhí)行上述命令后 , 輸出的結(jié)果如下 :
UNIX
System
4.13 q
函數(shù)參數(shù) q 表示跳離 sed 。其指令格式如下:
[address1] q
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) q 最多配合一個(gè)地址參數(shù)。
sed 執(zhí)行跳離動(dòng)作時(shí) , 它停止輸入 pattern space 數(shù)據(jù) , 同時(shí)停止數(shù)據(jù)送到標(biāo)準(zhǔn)輸出文件。
范例 :
題目: 對(duì)文件文件執(zhí)行 script_file 內(nèi)的編輯指令 , 除非遇到 "Linux" 字符串。
說(shuō)明: 無(wú)論 script_file 內(nèi)是何種指令 , 使用者只要在命令列上用指令/Linux/q , 函數(shù)參數(shù) q 會(huì)強(qiáng)迫 sed 遇到 "Linux" 時(shí)做跳離動(dòng)作。
sed 命令列如下 :
sed -e '/Linux/q' -f script_file input.dat
4.14 =
函數(shù)參數(shù) = 表示印出資料的行數(shù)。其指令格式如下:
[address1 ,[address2]] =
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) = 最多配合兩個(gè)地址參數(shù)。
執(zhí)行時(shí) , 行數(shù)將在數(shù)據(jù)輸出前先輸出。
范例 :
題目: 印出 input.dat 文件內(nèi)資料行數(shù)。假設(shè) input.dat 的內(nèi)容如下 :
The UNIX
Operating System
說(shuō)明 : 用函數(shù)參數(shù) = 來(lái)印出資料的行數(shù)。
sed 命令列如下 :
sed -e '=' input.dat
執(zhí)行上述命令后 , 輸出的結(jié)果如下 :
1
The UNIX
2
Operating System
4.15 #
在 script file 內(nèi) , 函數(shù)參數(shù) # 后的文字為注解。當(dāng)注解文字超過(guò)多行時(shí) , 其行間須以 "\" 換行字符相隔。
4.16 N
函數(shù)參數(shù) N 表示添加下一筆資料在 pattern space 內(nèi)。其指令格式如下:
[address1 ,[address2]] N
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) N 最多配合兩個(gè)地址參數(shù)。
sed 執(zhí)行時(shí) , 將下一行數(shù)據(jù)讀入并添加在 pattern space 內(nèi) , 數(shù)據(jù)行間以換行字符(embedded newline character)分隔。此外 , 在替換時(shí) , 換行字符可用 \n 來(lái) match。
范例 :
題目: 將下述兩行數(shù)據(jù)合并。假設(shè) input.dat 的內(nèi)容如下 :
The UNIX
Operating System
說(shuō)明 : 先利用函數(shù)參數(shù) N 將兩行數(shù)據(jù)置于 pattern space 內(nèi) , 在利用函數(shù)參數(shù) s/\n/ / 將兩行數(shù)據(jù)間的分隔號(hào) \n 以空白替代 , 如此兩行數(shù)據(jù)變成一行輸出。
sed 命令列如下 :
sed -e 'N' -e 's/\n/ /' input.dat
執(zhí)行上述命令后 , 其輸出的結(jié)果如下:
The UNIX Operating System
4.17 D
函數(shù)參數(shù) D 表示刪除 pattern space 內(nèi)的第一行資料。其指令格式如下:
[address1,address2]D
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) D 最多配合兩個(gè)地址參數(shù)。
函數(shù)參數(shù) D 與 d 的比較如下 :
當(dāng) pattern space 內(nèi)只有一數(shù)據(jù)行時(shí) , D 與 d 作用相同。
當(dāng) pattern space 內(nèi)有多行資料行時(shí)
D 表示只刪除 pattern space 內(nèi)第一行資料 ; d 則全刪除。
D 表示執(zhí)行刪除后 , pattern space 內(nèi)不添加下一筆數(shù)據(jù) , 而將剩下的數(shù)據(jù)重新執(zhí)行 sed script ; d 則讀入下一行后執(zhí)行 sed script。
范例 : 參考 section 3.3 的第二個(gè)例子。
4.18 P
函數(shù)參數(shù) P 表示印出 pattern space 內(nèi)的第一行資料。其指令格式如下:
[address1,address2] P
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) P 最多配合兩個(gè)地址參數(shù)。
P 與 p , 除了面對(duì)的 pattern space 內(nèi)的數(shù)據(jù)行數(shù)不同外 , 其它均相同。
范例(可與[section4.12]中的范例):
題目 : 輸出 input.dat 文件內(nèi)奇數(shù)行資料。假設(shè) input.dat 檔內(nèi)容如下:
The
UNIX
System
說(shuō)明: 在命令列上
以選項(xiàng) -n , 將數(shù)據(jù)輸出的控制權(quán)(參照[section2.5])轉(zhuǎn)給指令。
利用函數(shù)參數(shù) N 將偶數(shù)行添加至 pattern space 內(nèi)奇數(shù)行后。
利用函數(shù)參數(shù) P 將 pattern space 內(nèi)的第一行(奇數(shù)行)輸出。
在奇數(shù)行輸出后 , pattern space 內(nèi)剩下的數(shù)據(jù)行(偶數(shù)行)則被放棄輸出。最后 , 整個(gè)輸出只有原先的奇數(shù)行數(shù)據(jù)。
sed 命令列 :
sed -n -e 'N' -e 'P' infro.dat
執(zhí)行上述命令后 , 輸出的結(jié)果如下 :
The
System
4.19 h
函數(shù)參數(shù) h 表示暫存 pattern space 的資料至 hold space。其指令格式如下:
[address1 ,[address2]] h
對(duì)上述格式有下面幾點(diǎn)說(shuō)明 :
函數(shù)參數(shù) h 最多配合兩個(gè)地址參數(shù)。
sed 執(zhí)行暫存動(dòng)作時(shí) , 會(huì)蓋掉(overwrite) hold space 內(nèi)原來(lái)的數(shù)據(jù)。
當(dāng) sed 全部執(zhí)行結(jié)束時(shí) , hold space 內(nèi)數(shù)據(jù)會(huì)自動(dòng)清除。
范例 :參考 section 3.4 的例子。
4.20 H
函數(shù)參數(shù) H 與 h 唯一差別是 , sed 執(zhí)行 h 時(shí) , 數(shù)據(jù)蓋掉(overwrite) hold space 內(nèi)原來(lái)的數(shù)據(jù) , 而 H , 數(shù)據(jù)則是 "添加(append)" 在 hold space 原來(lái)數(shù)據(jù)后。例題請(qǐng)參考 section 3.2 之例一。
4.21 g
函數(shù)參數(shù) g 表示與函數(shù)參數(shù) h 相反的動(dòng)作 , 它表示將 hold space 內(nèi)資料放回 pattern space 內(nèi)。其指令格式如下 :
[address1,address2]g
函數(shù)參數(shù) g 最多配合兩個(gè)地址參數(shù)。
sed 執(zhí)行放回動(dòng)作時(shí) , 數(shù)據(jù)蓋掉(overwrite)(批注[13]) pattern space 內(nèi)原來(lái)的數(shù)據(jù)。
例題 :參考 section 3.4 的例子。
4.22 G
函數(shù)參數(shù) G 與 g 唯一差別是 , sed 執(zhí)行 g 時(shí) , 數(shù)據(jù)蓋掉(overwrite) pattern space 內(nèi)原來(lái)的數(shù)據(jù) , 而 G , 數(shù)據(jù)則是 "添加(append)" 在 pattern space 原來(lái)數(shù)據(jù)后。例子請(qǐng)參考 section 3.2 例一。
4.23 x
函數(shù)參數(shù) x 表示交換 hold space 與 pattern space 內(nèi)的數(shù)據(jù)。其指令格式如下 :
[address1 ,[address2]] x
函數(shù)參數(shù) x 大部份與其它處理 hold space 的函數(shù)參數(shù)一起配合。例如 , 將 input.dat 文件內(nèi)第 1 行資料取代第 3 行資料。此時(shí) , 用函數(shù)參數(shù) h 與 x 來(lái)配合。其中 , 以函數(shù)參數(shù) h 將第 1 資料存入 hold space ; 當(dāng)?shù)?3 行數(shù)據(jù)出現(xiàn)在 pattern space , 以函數(shù)參數(shù) x 交換 hold space 與 pattern space 的內(nèi)容。如此 , 第 3 行資料就被第 1 資料替代。其命令列如下:
sed -e '1h' -e '3x' input.dat
4.24 b、:label
函數(shù)參數(shù) : 與函數(shù)參數(shù) b 可在 sed script 內(nèi)建立類(lèi)似 BASIC 語(yǔ)言中 GOTO 指令的功能。其中 , 函數(shù)參數(shù) : 建立標(biāo)記;函數(shù)參數(shù) b 將下一個(gè)執(zhí)行的指令 branch 到標(biāo)記處執(zhí)行。函數(shù)參數(shù) : 與 b , 在 script file 內(nèi)配合的情況如下
.
.
.
編輯指令m1
:記號(hào)
編輯指令m2
.
.
.
[address1,[address2]]b [記號(hào)]
其中 , 當(dāng) sed 執(zhí)行至指令 [address1,[address2]]b [記號(hào)] 時(shí) , 如 pattern space 內(nèi)的數(shù)據(jù)符合地址參數(shù) , 則 sed 將下一個(gè)執(zhí)行的位置 branch 至由 :記號(hào)(批注[14])設(shè)定的標(biāo)記處 , 也就是再由 "編輯指令m2" ... 執(zhí)行。另外 , 如果指令中函數(shù)參數(shù) b 后沒(méi)有記號(hào) , 則 sed 將下一個(gè)執(zhí)行的指令 branch 到 script file 的最后 , 利用此可使 sed script 內(nèi)有類(lèi)似 C 語(yǔ)言中的 case statement 結(jié)構(gòu)。
范例 :
題目: 將 input.dat 文件內(nèi)數(shù)據(jù)行的開(kāi)頭字母重復(fù)印 40 次。假設(shè) input.dat 檔的內(nèi)容如下 :
A
B
C
說(shuō)明: 用指令 b p1 與 :p1 構(gòu)成執(zhí)行增加字母的循環(huán)(loop) , 同時(shí)在字母出現(xiàn) 40 個(gè)時(shí) , 也用指令 b 來(lái)跳出循環(huán)。下面就以文件內(nèi)第一行數(shù)據(jù) "A" 為例 , 描述它如何連續(xù)多添加 39 個(gè) "A" 在同一行:
用指令 s/A/AA/(參照 section4.1)將 "A" 替換成 "AA"。
用指令 b p1 與 :p1 構(gòu)成循環(huán)(loop) , 它目的使上述動(dòng)作被反復(fù)的執(zhí)行。每執(zhí)行一次循環(huán) , 則數(shù)據(jù)行上的 "A" 就多出一個(gè)。例如 , 第一次循環(huán)數(shù)據(jù)行變成 "AA" , 第二次循環(huán)資料行變成 "AAA" ...。
用指令 [ABC]\{40\}/b(批注[15]) 來(lái)作為停止循環(huán)的條件。當(dāng)數(shù)據(jù)行有連續(xù) 40 個(gè) A 出現(xiàn)時(shí) , 函數(shù)參數(shù) b 將執(zhí)行的指令跳到最后 , 停止對(duì)此行的編輯。
同樣 , 對(duì)其他數(shù)據(jù)行也如同上述的方式執(zhí)行。
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
基本上 , 函數(shù)參數(shù) t 與 函數(shù)參數(shù) b 的功能類(lèi)似 , 除了在執(zhí)行 t 的 branch 前 , 會(huì)先去測(cè)試其前的替換指令有沒(méi)有執(zhí)行替換成功外。在 script file 內(nèi)的情況如下:
.
.
.
編輯指令m1
:記號(hào)
編輯指令m2
.
.
.
s/.../.../
[address1,[address2]]t [記號(hào)]
編輯指令m3
其中 , 與函數(shù)參數(shù) b 不同處在于 , 執(zhí)行函數(shù)參數(shù) t branch 時(shí) , 會(huì)先檢查其前一個(gè)替換指令成功與否。如成功 , 則執(zhí)行 branch ; 不成功 , 則不 branch , 而繼續(xù)執(zhí)行下一個(gè)編輯指令 , 例如上面的編輯指令m3。
范例:
題目 : 將 input.dat 文件中資料 A1 替換成 C1、C1 替換成 B1、B1 替換成 A1。input.dat 檔的內(nèi)容如下:
代號(hào)
B1
A1
B1
C1
A1
C1
說(shuō)明 : input.dat 文件中全部數(shù)據(jù)行只需要執(zhí)行一次替換動(dòng)作 , 但為避免數(shù)據(jù)被替換多次 , 所以利用函數(shù)參數(shù) t 在 sed script 內(nèi)形成一類(lèi)似 C 語(yǔ)言中 case statement 結(jié)構(gòu) , 使每行數(shù)據(jù)替換一次后能立即用函數(shù)參數(shù) t 跳離替換編輯。
sed 命令列 :
sed -e '{
s/A1/C1/
t
s/C1/B1/
t
s/B1/A1/
t
}' input.dat
常用的 regular expression
--------------------------------------------------------------------------------
常用的 regular expression
普通字符 由普通字符所組成的 regular expression 其意義與原字符串字面意義相同。
^字符串 限制字符串必須出現(xiàn)于行首 。
$字符串 限制字符串必須出現(xiàn)行尾。
. 表示任意一字符。
[...] 字符集合, 用以表示兩中括號(hào)間所有字符當(dāng)中的任一個(gè) ,如 [^...]表示兩中括號(hào)間所有字符以外的字符。
-& 字符集合中可用"&"指定字符的范圍。
* 用以形容其前的字符(或字符集合)可重復(fù)任意多次 。
\n 表示嵌入新行字符(imbedded new line character)。
\(...\) 于 regular expression 中使用"\(" "\)"來(lái)括住一部份的 regular expression ; 其后可用"\1"來(lái)表示第一個(gè)被"\(" "\)"括住的部份。若 regular expression 中使用數(shù)次的"\(" "\)"來(lái)括住不同的部份 , 則依次使用"\1","\2","\3",...(最多可到"\9" 。
另外 , 在不同平臺(tái)上 , regular expression 會(huì)有一些不同的限制 , 詳細(xì)情況參照 appendix B。
HP-UX Release 9.01 與 SunOS 5.4 內(nèi) sed 對(duì) regular expression 中各種特殊字符的接受能力
regular expression 的特殊字符 HP-UX Release 9.01 SunOS 5.4
. 接受 接受
* 接受 接受
^ 接受 接受
$ 接受 接受
\ 接受 接受
[ ] 接受 接受
\( \) 與 \1 ... \9 合用 接受 接受
\{重復(fù)次數(shù)\} 接受 接受
\{下限,上限\} 接受 接受
\下限,\} 接受 接受
\< \> 不接受 接受
+ 不接受 不接受
? 不接受 不接受
| 不接受 不接受
( ) 不接受 不接受
& 接受 接受
批注
批注一.
就是后面將會(huì)提到的 sed script。
批注二.
指令 s/Unix/UNIX/ 表示將 "Unix" 替換成 "UNIX"。請(qǐng)參照 section 4.1。
批注三.
在指令中有 20 幾個(gè)函數(shù)參數(shù)可供選擇。
批注四.
以后這檔案稱(chēng)作 script file。
批注五.
編輯指令 1,10d 中 , 地址參數(shù)為 1,10 , 故 1 至 10 行的數(shù)據(jù)執(zhí)行函數(shù)參數(shù) d 所指定的刪除動(dòng)作。
批注六.
編輯指令 s/yellow/black/g 中 , 由于沒(méi)有地址參數(shù) , 故所有的數(shù)據(jù)行都要執(zhí)行函數(shù)參數(shù) s/yellow/black/g 所指定替換動(dòng)作。在函數(shù)參數(shù) s/yellow/black/g 中 , /yellow/black/g 為 s 的 argument , 其表示替換資料行中所有的 "yellow" 成 "black"。
批注七.
其命令格式如下 :
sed -n [-e 編輯指令].. [-f script_file].. [文件檔..]
批注八.
這些編輯指令中的函數(shù)參數(shù)可能是 p、l、s 的其中之一。
批注九.
在有些情況下 , 也可用編輯指令代替函數(shù)參數(shù)。例如 section3.3 之例二。
批注十.
這里 , sed script 是指 gp.scr 檔的內(nèi)容。它表示這一次 sed 執(zhí)行的編輯指令。
批注十一.
此函數(shù)參數(shù) , 表示替換掉(除掉) pattern space 內(nèi)兩行間的換行記號(hào)。 故 pattern space 內(nèi)只有一行資料。
批注十二.
/pattern/replacement/[flag] 為函數(shù)參數(shù) s 的 argument。
批注十三.
注意此時(shí) , 雖然資料是放回 pattern space , 但 hold space 的內(nèi)容還是不變。
批注十四.
注意 ":" 與記號(hào)間不可有空格。
批注十五.
地址參數(shù) [ABC]\{40\} , 表示 40 個(gè) A 字母或 40 個(gè) B 字母或 40 個(gè) C 字母。其中 [ABC] 表示 "A" 或 "B" 或 "C"; 其后的 \{40\} 表示其前的字母有 40 個(gè)。regular expression 請(qǐng)參照附錄 A |
|