剛剛看老男孩的博客關於sed的講解,很清晰。我整理記錄在案。
先熱熱身,取出good字符串。
# echo I am good student. | sed 's@^.*am \([a-z].*\) stu.*$@\1@g'
good
1.分隔符#,可以使用/,%,@等替代。
2.sed命令
s 查找並替換,將一個字符串替換成另一個
g 與s聯合使用時,表示對當前行全局匹配替換
p 打印匹配行
3.sed選項
-e 允許多項編輯
-n 取消默認輸出
4.正則表達式:
^word //以word開頭的行
Word$ //以Word結尾的行
. //匹配一個字符
*//匹配0個或多個字符
找出含有(es),(ess),(esss)等的字符串,注意,因爲(*)可以是0個,所以es也是符合搜索字符串。另外,因爲(*)爲重複“前一個字符”的符號,因此,在(*)之前必須要緊接一個重複字符。任意字符則爲(.*)
.* //匹配所有字符
5.sed中\( \)和\1的功能:
sed的\( \)功能可以記住正則表達式的一部分,其中,\1爲第一個記住的模式即第一個小括號中的匹配內容,\2第二記住的模式,即第二個小括號中的匹配內容,sed最多可以記住9個。
實例說明:
# echo I am good student. | sed 's@^.*am \([a-z].*\) stu.*$@\1@g'
a)^.*am□ //這句的意思是以任意字符開頭到am□爲止,匹配文件中的“I am□”字符串
b)\([a-z].*\)□ //這句的外殼就是括號\(\),裏面的[a-z]表示匹配26個字母的任何一個,[a-z].* 合起來就是匹配任意多個字符,本題來說就是匹配good字符串,由於good字符串是需要保留的,因此用括號括起來匹配,後面通過\1來取good字符串。
c)□stu.*$ //表示以空格tea起始任意字符結尾,實際就是匹配good字符串後,緊接着的字符串“□student.”。
d)後面被替換的內容中的\1就是取前面的括號裏的內容了,也就是我們要的good字符串。
取字符串的技巧
取出stat file顯示的權限數字
stat file | sed -n 's#^.*(0\([0-7].*\)\/-.*$#\1#gp'
^ 以什麼字符開頭
. 任意一個字符,這任意一個字符的含義有兩層:1.字符的數量只有一個 2.字符包含各種可打印字符,即ASCII碼集內的字符
* 重複前面的字符0次或者多次
^.*的含義就是以任意字符開頭並後面重複了任意字符的字符序列
(0 就是匹配stat file這個命令的結果中的第二行的第一個(0這個字符串
Access: (0644/-rw-r--r--) Uid: (
\([0-7].*\)
\(\) 在正則表達式中用來保存被匹配模式命中的字符串,並將它保存到1號寄存器裏面,可以使用\1來引用它。
可以看出來,針對本題,匹配了644這個字符序列。
\/-.*$
$ 正則表達式中用來表示行的結尾
就是匹配形如 字符序列中含有/-並緊接着任意字符序列的結尾
#\1#
這個表示的是,把前面的字符串用\1取代,這裏\1就是644
-n、p選項的作用
sed -n 取消對匹配模式命中的字符串的打印。
在sed的模式中使用p命令表示,打印顯示緩衝區(Linux的sed中使用的一個用來顯示屏幕內容的緩衝區)中的內容。
把 -n 和p結合使用,能指定要打印的內容。
p是打印符合匹配模式的輸入行,模式就是要打印的,加了p,就要打印兩次。
-n是取消默認打印。
那麼,-n和p聯合使用,就是隻打印符合匹配模式的內容一次。
正是因爲這兩個參數,就使得stat file的輸出內容的其他行不被打印出來,加上上面說的正則表達式的作用,就只顯示644這個內容。
練習
Sed取出ip地址
# ifconfig eth0 | grep "inet[^6]" | sed -n 's#^.*:\([0-9].*\) *B.*$#\1#gp' | sed 's#\s*$##g'
Sed取出mac地址
# ifconfig eth0 | grep "Link[^6]" | sed -n 's@^.* \([0-9].*\)@\1@gp'
Awk取出ip地址
# ifconfig eth0 | awk -F'[ :]+' 'NR==2{print $4}'
Awk取出mac地址
# ifconfig eth0 | awk -F' ' 'NR==1{print $5}'