在很多 shell 腳本的工作都從通過 grep 或 egrep 去除所需的文本開始。 正則表達式查找的最初結(jié)果,往往就成了要拿來作進一步處理的” 原始數(shù)據(jù)”。 通常,文本替換至少需要做一件事,就是講一些字以另一些字取代,或者刪除匹配行的某個部分。執(zhí)行文本替換的正確程序應該是 sed----流編輯器。
sed 的設計就是用來批處理而不是交互的方式編輯文件。 當藥做好幾個變化的時候,不管是對一個還是對數(shù)個文件,比較簡單的方式就是將這些變更部分寫到一個編輯的腳本里,再將此腳本應用到所有必須修改的文件,sed 的存在目的就在這里。
在 shell 里,sed 主要用于一些簡單的文本替換,所以我們先從他開始。
基本用法:
我們經(jīng)常在管道中間使用 sed,用來執(zhí)行替換操作,做法是使用 s 命令 ---- 要求正則表達式尋找,用替換文本替換匹配的文本呢,以及可選的標志:
sed ‘s’:.*//’ /etcpasswd |
刪除第一個冒號之后所有的東西sort -u
排序列表并刪除重復部分sed 的語法:
sed [-n] ‘editing command’ [file...]
sed [-n] -e ‘editing command’ [file...]
sed [-n] -f script-file... [file...]
用途:
sed 可刪除 (delete)、改變 (change)、添加 (append)、插入 (insert)、合、交換文件中的資料行,或讀入其它檔的資料到文 > 件中,也可替換 (substuite) 它們其中的字串、或轉(zhuǎn)換 (tranfer) 其中的字母等等。例如將文件中的連續(xù)空白行刪成一行、"local" 字串替換成 "remote"、"t" 字母轉(zhuǎn)換成 "T"、將第 10 行資料與第 11 資料合等。
總合上述所言,當 sed 由標準輸入讀入一行資料并放入 pattern space
時,sed 依照 sed script
的編輯指令逐一對 pattern space
內(nèi)的資料執(zhí)行編輯,之後,再由 pattern space
內(nèi)的結(jié)果送到標準輸出,接著再將下一行資料讀入。 如此重執(zhí)行上述動作,直至讀完所有資料行為止。
記住:
主要參數(shù):
sed -e 'command' file(s)
sed -f scriptfile file(s)
pattern space
。行為模式:
讀取輸入文件的每一行。 假如沒有文件的話,則是標準輸入。 以每一行來說,sed 會執(zhí)行每一個應用倒數(shù)入行的 esiting command
。 結(jié)果會寫到標準輸出 (默認情況下,或是顯式的使用 p 命令及 -n 選項)。 若無 -e 或 -f 選項,則 sed 會把第一個參數(shù)看做是要使用的 editing command
。
find /home/tolstoy -type -d -print
// 尋找所有目錄sed ‘s;/home/tolstor;/home/lt/;’
// 修改名稱; 注意: 這里使用分號作為定界符sed ‘s/^/mkdir /’
// 插入 mkdir 命令sh -x
// 以 shell 跟蹤模式執(zhí)行上述腳本是說將 /home/tolstoy
目錄結(jié)構建立一份副本在 /home.lt
下 (可能是為備份) 而做的準備
替換案例:
Sed 可替換文件中的字串、資料行、甚至資料區(qū)。其中,表示替換字串的指令中的函數(shù)參數(shù)為 s; 表示替換資料行、或資料區(qū) > 的指令中的函數(shù)參數(shù)為 c。上述情況以下面三個例子說明。
* 行的替換
sed -e '1c/#!/bin/more' file (把第一行替換成#!/bin/more)
思考: 把第 n 行替換成 just do it
sed -e 'nc/just do it' file
sed -e '1,10c/I can do it' file (把 1 到 10 行替換成一行:I can do it)
思考: 換成兩行 (I can do it! Let's start)
sed -e '1,10c/I can do it!/nLet'"/'"'s start' file
* 字符的替換
$ sed 's/test/mytest/g' example
----- 在整行范圍內(nèi)把 test 替換為 mytest。如果沒有 g 標記,則只有每行第一個匹配的 test 被替換成 mytest。$ sed -n 's/^test/mytest/p' example
-----(-n) 選項和 p 標志一起使用表示只打印那些發(fā)生替換的行。也就是說,如果某一行開頭的 test 被替換成 mytest,就打印它。$ sed 's/^192.168.0.1/&localhost/' example
-----& 符號表示替換換字符串中被找到的部份。所有以 192.168.0.1 開頭的行都會被替換成它自已加 localhost,變成 192.168.0.1localhost。$ sed -n 's/loveable/\1rs/p' example-----love
被標記為 1,所有 loveable 會被替換成 lovers,而且替換的行會被打印出來。$ sed 's#10#100#g' example
----- 不論什么字符,緊跟著 s 命令的都被認為是新的分隔符,所以,“#” 在這里是分隔符,代替了默認的 “/” 分隔符。表示把所有 10 替換成 100。替換與查找
在 s 命令里以 g 結(jié)尾表示的是: 全局性,意即” 替代文本取代正則表達式中每一個匹配的”。 如果沒有設置 gsed 指揮取代第一個匹配的。
鮮為人知的是: 可以在結(jié)尾指定數(shù)字,只是第 n 個匹配出現(xiàn)才要被取代:
sed ‘s/Tom/Lisy/2’ < Test.txt
僅匹配第二個 Tom
通過給 sed 增加一個 -e 選項的方式能讓 sed 接受多個命令。sed -e ‘s/foo/bar/g’ -e ‘s/chicken/cow/g’ myfile.txt 1>myfile2.txt
用 shell 命令將 test.log 文件中第 3-5 行的第 2 個“filter” 替換成“haha”sed -i '3,5s/filter/haha/2' test.log