sed使用心得

sed 是一種UNIX/LINUX 平臺下的輕量級流編輯器,日常一般用於處理文本文件。sed 有許多很好的特性。首先,它相當小巧;其次, sed 可以配合強大的 shell 完成許多複雜的功能。在我看來,sed完全可以看成一個腳本解釋器,用類似於編程的手段完成許多事情。
sed簡單示例
sed命令的格式是
sed [-options] [command] [stdin]
比如這個例子
$ sed –e ‘d’ ./Mydir/Myfile
執行該命令,將得不到任何輸出。在該例中,用一個編輯命令 'd' 調用 sed;sed 打開 ./Mydir/Myfile 將一行讀入其模式緩衝區,執行’d’(“刪除行”);然後打印模式緩衝區(緩衝區已爲空);它對後面的每一行重複這些步驟,這不會產生輸出!
對這個命令要說明的幾點是:首先,它根本沒有修改 ./Mydir/Myfile。這是因爲 sed 是流處理器,它只讀取在命令行指定的文件,它不試圖修改該文件。其次, sed 是面向行的,'d' 命令不是簡單地告訴 sed 一下子刪除所有輸入數據;相反,sed 逐行將 ./Mydir/Myfile 的每一行讀入其稱爲模式緩衝區的內部緩衝區,一旦將一行讀入模式緩衝區,它就執行 'd' 命令,然後打印模式緩衝區的內容。最後要注意的事是括起 'd' 命令的單引號的用法,這樣可以禁用 shell 擴展。
指定sed的作用範圍
看下面的三個例子
$ sed –e ‘1d’ ./Mydir/Myfile
$ sed –e ‘1,10d’ ./Mydir/Myfile
$ sed –e ‘/begin/,/end/p’ ./Mydir/Myfile
第一個例子說明只刪除./Mydir/Myfile第一行的緩衝,第二個例子將刪除第1~10行的緩衝。第三個例子最複雜,它定義了以字符串’begin’開始到’end’結束的作用範圍
sed中的正則表達式
sed支持正則表達式,比如
$ sed –n -e ‘/regexp/p’ ./Mydir/Myfile
比如要刪除所有的空行
$ sed –e ‘/^$/d’ ./Mydir/Myfile
sed中的一些特殊定義是
規則 表達式 描述
/./ 將與包含至少一個字符的任何行匹配
/../ 將與包含至少兩個字符的任何行匹配
/^#/ 將與以 '#' 開始的任何行匹配
/^$/ 將與所有空行匹配
/}^/ 將與以 '}'(無空格)結束的任何行匹配
/} *^/ 將與以 '}' 後面跟有 零或多個空格結束的任何行匹配
/[abc]/ 將與包含小寫 'a'、'b' 或 'c' 的任何行匹配
/^[abc]/ 將與以 'a'、'b' 或 'c' 開始的任何行匹配

再比如一個經典的例子,打印c源代碼中的main函數內容,其命令可以寫成如下
$ sed –n –e ‘/main[[:space]]*(/,/^}/p’ ./Mydir/*.c
其中[:space]表示空格,[[:space]]*表示有0~多個空格,所以main[[:space]]*(的意思是匹配“main (”字符串;“^}”表示這一行有且只有一個字符}。當然,上面的命令不是十分嚴謹。
sed –e ‘s/regexp/repalcement’ file
替換是sed命令中最常用的命令,比如如下的例子
$ sed –e ‘s/a/b’ ./Mydir/Myfile
$ sed –e ‘s/a/b/g’ ./Mydir/Myfile
第一個命令將./Mydir/Myfile中每一行第一次出現的字符a替換成字符b;第二個命令由於加入了’/g’,表示是全局(全部)替換字符a成字符b。
經常還可以看見如下兩種形式的sed
$ sed –e ‘1,10s/a/b’ ./Mydir/Myfile
$ sed –e ‘/^$/,/^END/s/a/b/g’ ./Mydir/Myfile
第一個命令是指替換1~10行;第二個命令是指全局替換從空行開始到以END開始的行中的內容。
替換命令不一定非要以/分隔,比如
$ sed –e ‘s:usr/local:/usr:g’ ./Mydir/Myfile
就是將./Mydir/Myfile中的usr/local全部替換成/usr
要用好替換命令,當然要使用正則表達式,除了上面所說的表達式的例子,還有一些是非常有用的
字符類 描述
[:alnum:] 字母數字 [a-z A-Z 0-9]
[:alpha:] 字母 [a-z A-Z]
[:blank:] 空格或製表鍵
[:cntrl:] 任何控制字符
[:digit:] 數字 [0-9]
[:graph:] 任何可視字符(無空格)
[:lower:] 小寫 [a-z]
[:print:] 非控制字符
[:punct:] 標點字符
[:space:] 空格
[:upper:] 大寫 [A-Z]
[:xdigit:] 十六進制數字 [0-9 a-f A-F]

比如下面這個例子
$ sed –e ‘s/<[^>]*>//g’ ./Mydir/Myfile
< [^>]*>匹配<…>這樣的字符串(…中不含>)。運行這個命令,能夠將 “<b>This</b> is what <b>I</b> meant.”這樣的字符串替換成“This is what I meant.”
考察如下的命令
$ sed -e 's/.*/# &/' ./Mydir/Myfile
這個命令將所有的非空行以“#”註釋掉——&告訴sed在行首插入字符。
‘s///’允許我們在規則表達式中定義區域,然後可以在替換字符串中引用這些特定區域。這些區域是以(和)隔開的。
比如定義三個匹配非空字符的區域'(.*) (.*) (.*)',現在可以定義這三個區域的動作,比如
$ sed -e 's/(.*) (.*) (.*)/PreFix 1-2 Fix 3/' ./Mydir/Myfile
假如把三個區域分別命名爲a、b、c,則最後結果是 PreFix a-b Fix c
sed中組合命令
sed中的命令可以組合,以;號隔開,比如
$ sed –n –e ‘=;p’ ./Mydir/Myfile
=表示打印行號,p表示打印。對於更復雜的指令,則可以寫成命令腳本,然後用-f選項導入,比如
$ sed –n –f MyScript.sed ./Mydir/Myfile
對於同一個地址上的操作,則可以用{}組合,比如
$ sed –n ‘1,20{ s/samba/Samba/g s/posix/POSIX/g }’ ./Mydir/Myfile
sed中的行附加命令
在當前行之前插入行“i”,如果要插入多行,則將多行用分隔
在當前行之後插入行“a”,用法和上面相似
更改當前行“c”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章