寫在前言:作為一名系統管理員,特別是Linux(Unix)方向的,對於Sed和Awk 這兩個工具,是必須得掌握的!
一、有關ED行編輯器
發展歷程:ED(Unix最初的行編輯器)——>EX(vi底層的行編輯器)——>grep&sed——>Awk
ed:Unix最初行編輯器,可交互使用,每次可以處理一行,當打開一個文本或文件時,它都會停留在最后一行
grep:是從ed中提取出來的,並可以做外部程序的行編輯命令,它作為執行一個編輯命令的硬連接
sed:作為一個為特別目的面建立的編輯器,不可交互使用,面向字符流,專門用於執行腳本
awk:作為一種可編程的編輯器,面向字符流,並可解釋編輯命令腳本,廢棄了sed的行編輯命令集,仿效C語言
與ED相關
#ed test.txt //打開test.txt文件,它是一個測試文件!
#ed test < scrpte-ed //這樣的執行ed的腳本,scrpte-ed里面就是ed的命令腳本
相關的ed命令集:
p ——>打印當前所在行,當然也可以指定地址打印出行,如120p,全局打印(grep):g/re/p
d ——>刪除當前所在行,當然也可以指定地址刪除,如100d,匹配正則表示為:[g]/regular/d,g表示全局(可選)
s ——>替換命令,定義為:[g][address]s/pattern/replacement/flag[g],pattern為正則表達式,
replacement為當前想替換的字符串,前面的g表示全局,后面的g表示同行中的所有,不只是第一個出現(默認是第一個出現為替換)
如g/installing/s/regular/replacestring/g,表替換文檔中所有以installing開頭的行r中內容為regular 為replacestring
q ——>退出,當在工作時,要連續兩次輸入q方可以退出ed
二、與SED和AWK相關
SED 與 AWK 語法模式
command [options] script filename
script為要執行的指令,假若它包含由shell可解釋的空格或任意字符(如 * 和 $ ),那么它必須得用單括號引起
在sed和awk中,每個指令都包含兩個部分:模式和語句 ,其中 模式是由“/”分隔的正則,語句指定一個或多個將被執行的動作
1、sed
調用方法:在命令行上指定編輯命令或將命令存放在一個文檔中並在命令行上指定文檔
命令:
#sed [-n|-e] 'instruction' file //只有多個命令一起時才加參數e,單引號的是要執行的命令,file是要進行操作的文檔或文件
如#sed 's/Installing/myreplace' test.txt
由於sed默認是輸出所有輸入的行的,加n可以阻止它自動輸出,但這樣也會是影響到每個要生成輸出的指令,所以我們要在instruction后加/p打印顯示
如#sed -n -e 's/Installing/myreplace' test.txt
#sed -f scriptfile file //執行sed腳本,scriptfile為腳本名
#sed -f scriptfile file > outputfile //重定向IO將結果輸出到outputfile文件中
下圖總結sed的參數:
2、awk
調用方法與sed類似,可以在命令行上指定指令或創建腳本文件
#awk '/pass/{instruction}' file //指令中,必須得用大括號包起來
#awk -f[-F,] scriptfile file //f意義與sed一樣,F選項是將字段分隔符改變為逗號,可以讓我們檢索多個字段,如awk -F,'{print $1;print $2;print $3}' file
下圖表示相關awk參數
解釋:awk記錄,為每個輸入行的解釋;awk字段,為每個輸入行上的每個單詞(包括空格或制表符分隔);awk定界符,為一個或多個連續的空格或制表符。
應用:允許在模式或過程中引用這些字段,其中$0 表整個輸入行,$1/$2/$3````表示輸入行上的各個字段
如:awk '/installing/{print $1}' test.txt //打印test文檔中,帶installing行的第一個字段
三、正則表達式
1、元字符句點“.”與元字符星點“*”
句點表示,通配任何單個字符,如A.E,通配的可以有類似ACE/AEE/AKE等
星點表示,通配它前面零個或多個字符,如A*E,可通配類似ASLOE/ACE/ALLOLOE等
句點與星點合用,綜合前面兩個,如A.*E,可通配"A.E"匹配的字符,也可以是"A"和"E”間任意數目的字符
例子:#grep 'seten.' test.txt //匹配“seten”后有任何一個字符的行,但不包括以seten結尾的行(除非行后有字符)
通配表示總表
2、字符類
它是對通配符的改進,使用方括號"[]"將字符列表括起來,其中每個字符占一個位置
如[W|w]hat //它對大小寫的匹配,非常好用,這樣的就表示可以匹配"What"或"what"了,包括第一個字符是“W”或"w"的4個字符的字符串的行
當然也有個比較好用的取文章章節的標題,如#grep '\.H[12345]' ch0 [123]
以下是方括號相關參數的表
3、 字符的范圍
用字符“-”表示,匹配一些字符的范圍。如[a-z]或[A-Z]或[0-9]
實例:[0-9z-aA-Z,.;:'"?] 或[0-9a-zA-Z][,.?;:'"]
當然匹配日期是比較好的,如
YY-MM-DD
可以表示成:[0-9][0-9][-/][0-1][0-9][-/][0-3][0-9]
其中“-”和"/"都是定界符,要確保它在字符類中解釋為字面意思,即作為一個連字符而不是指一個通配范圍
4、POSIX字符類
對正則表達式字符和操作符的含義進行了形式化,定義了兩類正則表達式:基本的正則表達式(BRE),而grep和sed就是使用這種;擴展的正則表達式,而egrep和awk就是使用這種表達式。
以下是它的匹配相關的內容
5、好用匹配命令
#grep '^$' test.txt //統計文本中的空行數目
解釋Norff與Troff:
nroff 和 troff 是將文本文件格式化為打印機所需要的格式的 UNIX 命令 ( 和支持它們的程序) 。 (為開始打印還有其他的 UNIX 指令)。nroff 被設計來為行式打印機和高質量字母打印機格式化輸出。troff設計用來為排字機格式化輸出。 troff 包含一些只適合於排字機的特別的功能; 否則,這兩個命令是一樣的哪一個都可以使用。 一般來說,文本文件被設計和 nroff或 troff一起使用,文件包含內置的代碼例如行距、頁邊空白設定、居中、定位鍵停止、段中不分頁等等。 命令本身包括適用於整個文件的選項。 nroff 和 troff 提供有關和 IBM 的Script/VS 語言相同水平的格式化控制。一般來說,在這一個水平的文本格式語言有一個缺點,在非打印媒體 ( 例如在網絡上)中再使用比較困難。 這一個缺點導致非輸出特殊標記的發展,這個標記一般用標准通用標記語言定義,在標記中邏輯的或函數的描述被應文本元素,特殊設備程序能以適當的方式解釋這些文本元素。 nroff/ troff 格式碼的例子包括: .ce使文本的下一行居中。 .sp跳越一個行間距。 .ps 10使用 10 點的類型。 nroff/ troff 的一個流行的 UNIX 替換者的是叫做 TeX的格式程序。 TeX 被設計給使用者對字型選擇和文本安排的很多控制,尤其是支持包含數學符號的文本。 如果你已經繼承了一個 nroff/ troff 文件並需要將它轉換成 HTML, 你可能能夠找到一個工具將文件轉換成 HTML"預先格式化"文本( 意思是文件將會看起來好像已經從某處被引進 )。 然而這可能是一些情形下的暫時解決辦法,很有可能最后你必須手動剝去老的代碼並用新的格式開始(使用 HTML 標簽) 。
四、Sed 四種腳本類型
忠告:編寫腳本文件時,對於初學都最好的方法是一行一行編寫並調試的方法,因為這樣分隔開來就很容易看到那些命令實現了那些功能,當我們進行多行命令編輯時,若出現問題我們得一行一行往回刪除,直到找到問題為止
1、對同一文件進行多重編輯
s/^$/.LP/ ——>匹配所有空行,用“.LP”來取代 /^+ */d ——>刪除以“+”開始並包含行式打印機下划線的行 s/^ *// ——>刪除行開始位置有填充的空格s/ */ /g ——>連續空格的用一個空格替代 s/\. */. /g ——>句點后一個或多個空格的用兩個空格替代
2、改變一組文件(Sed 最常使用的)
編寫的腳本,要選擇有代表性的幾個文檔進行測試,但並非通過測試了的腳本對於任何一個文檔也都可以達到我們的預想效果,若出現我們不想的或沒有出現我們想要的結果,我們還得再修改腳本
3、提取文件內容
sed -n '/^\.deBL/,/^\.\.$/p' /usr/lib/``` ——>匹配范圍以“.deBL”開始到“..”結束
例子:
#!/bin/sh sed -n ' s/'//g ——>刪除引號 s/\.Se /Chapter /p ——>替換章標題 s/\.Ah /•A. /p ——>替換節標題 s/\.Bh /••B. /p ——>替換子標題 ' $* ——>對命令行上指定的文件起作用
4、編輯工作轉移
sed作為一個流編輯器,在管理中應用編輯操作,而這些操作永遠不會被寫入到編輯文檔中去
s/^"/‘‘/
s/'$/’’/
s/'? /’’? / g
s/*?$/’’?/g
s/ "/ ‘‘/g
s/* /’’ /g
s/•"/•‘‘/g
s/'•/’’•/g
s/')/’’)/g
s/']/’’]/g
s/("/(‘‘/g
s/\["/\[‘‘/g
s/";/’’;/g
s/":/’’:/g
s/,"/,’’/g
s/",/’’,/g
s/\."/.\\\&’’/g
s/"\./’’.\\\&/g
s/\\(em\\^"/\\(em ‘‘/g
s/\\(em/’’\\(em/g
s/\\(em"/\\(em‘‘/g
s/@DQ@/"/g
注:第一行命令是找開始處的引號將它替換成左引號,第二行是將最后行的引號替換成右引號,剩下的就是找上下文中的引來並替換成相應的符號,最后一個是允許我們為troff提供真正的引號(")
五、基本Sed命令
sed的命令集是由25個命令組成,下面介紹主要常用的幾個命令
命令基本格式
[address] command
對於只能接受單個地址行的命令基本格式
[line-address] command
對於命令組,可以用大括號包起來作用於同一個地址
[address] {
command1
command2
command3
}
注:第一個大括號可以與command1同行,但最后的大括號不能與最近的命令同行,必須得它自己一行
1、替換——>"s"
命令格式:
[address] s/pattern/replacement/flags
flags:n/g/p/w,其中n為1-512,表示對文件第n次出現的情況進行替換;g,等同全局變量;p,打印;w file,將模式空間的內容寫到文件file中
replacement:比較有特別意義的幾個字符,&、\n、\ :分別是用正則表達式匹配的內容替換、匹配第n個子串(n是個數字)、轉義字符
1.1、替換元字符——>"\"、"&"、"\n"
注:
反斜杠用於轉義其他元字符,但它在替換字符串時,也可用於包含換行字符;
與稱號用於可變的字符中,這個特別管用也可用於替換整個匹配的內容
一些例子:
sed 's/\(.*\).*:\(.*\)/\2:\1/' changefile ——>將行中用冒號分開的兩部分交換
s/See section [1-9][0-9]*\.[1-9][0-9]*/(&)/ ——>匹配類似”See section 12.9“或”See section 9.12“
1.2、校正索引條目
針對文章或書本的索引,我們可以用過濾的方法將其中的章節都提取出來
看懂以下
#!/bin/sh
grep "^\.XX" $* | sort -u |
sed 's/^\.XX \(.*\)$/\/^\\.XX \/s\/\1\/\1\//'
第一行,用grep獲取命令行文本的索引並交給sort排序和刪重復,最后給sed進行過濾
2、刪除——>"d"
如某行匹配這個刪除命令的地址,那么就刪除整行,而不是只刪除匹配的內容(除非你有特別指定或用替換命令來取代刪除),當然也可以用於特別指定刪除兩個地址之間的文件內容,命令格式可參考
/^\.sp/d
/^\.np/d
3、追加、插入、更改
使用時,必須指定在多行上,所以在sed中,不太常用!前兩個命令只應用於單個地址,不能匹配地址范圍,而最后的更改卻是可以的
[line-address]a\
text ——>追加
[line-address]i\
text ——>插入
[address]c\
text ——>更改
例子:
/<Larry's address>/i\
14400 cross count\
frech linck,inter
——>在匹配”<Larry's address>“的地方插入兩行文本
4、列表——>"l"
將非打印的字符顯示為兩個數字的ASCII代碼
在sed中不能用ASCII值匹配字符,當然也不能用八進制數值匹配字符
5、轉換——>“y”
特有的命令,它按位置將字符串中的abc每個字符,都轉換成字符串xyz中的等價字符
[address] y/abc/xyz/
6、打印——>"p"