最近一直在研究shell指令碼這塊,剛好閑下來整了下自己手頭上比較好的資料中的一些範例,以下是我整理的鳥哥私房菜裡面Regex裡面比較基礎的一些文法詳解,適合新手查閱。
首先先複製一段範例:
複製代碼 代碼如下:
# vi regular_express.txt
-------------------------------
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn't fit me.
However, this dress is about $ 3183 dollars.
GNU is free air not free beer.
Her hair is very beauty.
I can't finish the test.
Oh! The soup taste good.
motorcycle is cheap than car.
This window is clear.
the symbol '*' is represented as start.
Oh!My god!
The gd software is a library for drafting programs.
You are the best is mean you are the no. 1.
The world <Happy> is the same with "glad".
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let's go.
# I am VBird
--------------------------------
設定語係為C
複製代碼 代碼如下:
#export LANG=C
grep
1.搜尋特定字串"the"
注: n為顯示行號
複製代碼 代碼如下:
# grep -n 'the' regular_express.txt
2.反向搜尋特定字串"the"
複製代碼 代碼如下:
# grep -vn 'the' regular_express.txt
3.取得任意大小寫"the"的這個字串
複製代碼 代碼如下:
# grep -in 'the' regular_express.txt
4.利用括弧 [] 來搜尋集合字元
搜尋test或taste這兩個單詞時,發現他們有共同的't?st',所以可以這麼搜尋
複製代碼 代碼如下:
# grep -n 't[ae]st' regular_express.txt
這樣其實就是在找t[a]st和t[e]st這兩個分開的字元
如果搜尋有 oo 的字元時,則可以使用:
複製代碼 代碼如下:
# grep -n 'oo' regular_express.txt
如果搜尋oo時不想搜到 oo 前面有 g 的話,我們可以利用反向選擇[^]來達成:
複製代碼 代碼如下:
# grep -n '[^g]oo' regular_express.txt
如果搜尋oo前面不想有小寫字元,則:
複製代碼 代碼如下:
# grep -n '[^a-z]oo' regular_express.txt
注: 大寫英文/小寫英文/數字 可以使用 [a-z]/[A-Z]/[0-9]等方式來書寫,也可以寫在一起
[a-zA-Z0-9]表示要求字串是數字以及英文
如果我們要取得有數位那行,則:
複製代碼 代碼如下:
# grep -n '[0-9]' regular_express.txt
註:但考慮到語系對編碼順序的影響,因此除了連續編碼使用減號[-]外,也可以用[:lower:]代替a-z 以及 [:digit:] 代替0-9 使用
複製代碼 代碼如下:
# grep -n '[^[:lower:]]oo' regular_express.txt
# grep -n '[[:digit:]]' regular_express.txt
5.顯示行首為'the'的字串
複製代碼 代碼如下:
# grep -n '^the' regular_express.txt
顯示行首是小寫字元
複製代碼 代碼如下:
# grep -n '^[a-z]' regular_express.txt
6.顯示行尾為點 . 的那一行
複製代碼 代碼如下:
# grep -n '\.$' regular_express.txt
7.顯示5-9行資料
複製代碼 代碼如下:
# cat -An regular_express.txt |head -n 10 |tail -n 6
8.顯示空白行
複製代碼 代碼如下:
# grep -n '^$' regular_express.txt
9.找出g??d字串,起頭g結束d的四個字串
複製代碼 代碼如下:
# grep -n 'g..d' regular_express.txt
10. o*代表Null 字元(就是有沒有字元都可以)或者一個到N個o字元,所以grep -n 'o*' regular_express.txt就會把所有行全部列印出來,
11.oo*代表o+Null 字元或者一個到N個o字元,所以grep -n 'oo*' regular_express.txt就會把o,oo,ooo等的行全部列印出來
12."goo*g"代表gog,goog,gooog...等
複製代碼 代碼如下:
# grep -n 'goo*g' regular_express.txt
13.找出含g...g字串的行
注: .代表任一字元, .*則就代表Null 字元或者一個到N個任一字元
複製代碼 代碼如下:
# grep -n 'g.*g' regular_express.txt
14.找出含有數位行
複製代碼 代碼如下:
# grep -n '[0-9][0-9]*' regular_express.txt
或# grep -n '[0-9]' regular_express.txt
15.找出含兩個o的字串
注:{}因為在shell裡有特殊意義,所以需要加跳脫符\來讓其失去意義
複製代碼 代碼如下:
# grep -n 'o\{2\}' regular_express.txt
找出g後含2到5個o然後以g結尾的字串
複製代碼 代碼如下:
# grep -n 'go\{2,5\}g' regular_express.txt
找出g後含2以上的o然後以g結尾的字串
複製代碼 代碼如下:
# grep -n 'go\{2,\}g' regular_express.txt
總結:
^word 表示帶搜尋的字串(word)在行首
word$ 表示帶搜尋的字串(word)在行尾
. 表示1個任一字元
\ 表示逸出字元,在特殊字元前加\會將原本的特殊字元意義去除
* 表示重複0到無窮多個前一個RE(Regex)字元
[list] 表示搜尋含有list的字串
[n1-n2] 表示搜尋指定的字串範圍,例如[0-9] [a-z] [A-Z]等
[^list] 表示反向字串的範圍,例如[0-9]表示非數字字元,[A-Z]表示非大寫字元範圍
\{n,m\} 表示找出n到m個前一個RE字元
\{n,\} 表示n個以上的前一個RE字元
egrep總結:
+ 表示重複一個或一個以上的前一個RE字元
範例:egrep 'go+d' regular_express.txt
表示搜尋(god)(good)(goood)...等等字串,o+代表[一個以上的o]
? 表示重複零個或一個的前一個RE字元
範例:egrep 'go?d' regular_express.txt
表示搜尋(gd)(god)字串,o?代表[空的或1個o]
注:egrep下'go+d'和'go?d'的結果集合就等於grep下的'go*d'
| 表示用或(or)的方式找出數個字串
範例:egrep 'gd|good|dog' regular_express.txt
表示搜尋(gd)或(god)或(god)字串,|代表或
() 表示找出群組字串
範例:egrep 'g(la|oo)d' regular_express.txt
表示搜尋(glad)或(good)字串
() +表示找出多個重複群組的判別
範例: echo 'AxyzxyzxyzxyzxyzC'|egrep 'A(xyz)+C'
表示搜尋開頭是A結尾是C,中間有一個以上的'xyz'字串
sed:
插入:
1.將/etc/passwd 的內容列出並列印行號,同時,將2-5行刪除顯示
複製代碼 代碼如下:
# nl /etc/passwd | sed '2,5d'
注: sed是sed -e的簡寫, 後接單引號
同上刪除第2行
複製代碼 代碼如下:
# nl /etc/passwd | sed '2d'
同上刪除第三行到最後一行
複製代碼 代碼如下:
# nl /etc/passwd | sed '3,$d'
2.在第二行後加上一行test
複製代碼 代碼如下:
# nl /etc/passwd | sed '2a test'
在第二行前加上一行test
複製代碼 代碼如下:
# nl /etc/passwd | sed '2i test'
在第二行後加入兩行test
複製代碼 代碼如下:
# nl /etc/passwd | sed '2a test \
> test'
替換行:
3.將2-5行內容取代為 No 2-5 number
複製代碼 代碼如下:
# nl /etc/passwd | sed '2,5c No 2-5 number'
4 列出/etc/passwd 內第5-7行
複製代碼 代碼如下:
# nl /etc/passwd |sed -n '5,7p'
替換字串:
sed 's/被替換字串/新字串/g'
1.擷取本機IP的行
複製代碼 代碼如下:
# /sbin/ifconfig eth0 |grep 'inet addr'
將IP前面的部分予以刪除
複製代碼 代碼如下:
# /sbin/ifconfig eth0 |grep 'inet addr'| sed 's/^.*addr://g'
將IP後面的部分刪除
複製代碼 代碼如下:
# /sbin/ifconfig eth0 |grep 'inet addr'| sed 's/^.*addr://g'| sed 's/Bcast:.*$//g'
-------------------
192.168.100.74
-------------------
2.用grep將關鍵詞MAN所在行取出來
複製代碼 代碼如下:
# cat /etc/man.config |grep 'MAN'
刪除批註行
複製代碼 代碼如下:
# cat /etc/man.config |grep 'MAN'| sed 's/^#.*$//g'
刪除空白行
複製代碼 代碼如下:
# cat /etc/man.config |grep 'MAN'| sed 's/^#.*$//g'| sed '/^$/d'
3.利用sed將regular_express.txt內每一行若為.的換成!
註:-i參數會直接修改文本,而並非直接輸出
複製代碼 代碼如下:
# sed -i 's/.*\.$/\!/g' regular_express.txt
4.利用sed在文本最後一行加入 #This is a test
注: $代表最後一行 a代表行後添加
複製代碼 代碼如下:
# sed -i '$a #This is a test' regular_express.txt
將selinux設定檔enforcing改成disabled
複製代碼 代碼如下:
# sed -i '6,6c SELINUX=disabled' /etc/selinux/config
延伸正規標記法:
複製代碼 代碼如下:
# grep -v '^$' regular_express.txt |grep -v '^#'
延伸寫法:
複製代碼 代碼如下:
# egrep -v '^$'|'^#' regular_express.txt
1. +表示重複一個或一個以上的前一個RE字元
例如:egrep -n 'go+d' regular_express.txt
普通寫法: grep -n 'goo*d' regular_express.txt
2. ?表示重複零個或一個前一個RE字元
例如: egrep -n 'go?d' regular_express.txt
3. |表示用或的方式找出數個字串
例如: egrep -n 'gd|good' regular_express.txt
4. ()表示找出群組字串
例如: egrep -n 'g(la|oo)d' regular_express.txt
也就是搜尋(glad)或good這兩個字串
5. ()+多個重複群組判別
例如: echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C'
也就是要找開頭是A結尾是C 中間有一個以上的'xyz'字串的意思
awk:
1.用last取出登陸資料前五行
複製代碼 代碼如下:
# last -n 5
取出帳號與登陸者IP,且帳號與IP之間以TAB隔開
複製代碼 代碼如下:
# last -n 5 |awk '{print $1 "\t" $3}'
注:$1代表用空格或TAB隔開的第一個欄位,以此類推。。
$0代表該行全部欄位
複製代碼 代碼如下:
# last -n 5 |awk '{print $1 "\t lines:" NR "\t columes:" NF}'
注: NF代表每一行的$0的欄位總數
NR代表目前awk所處的是第幾行資料
FS代表目標分隔字元,預設為空白格
2.在/etc/passwd中以:來作為分段字元,則我們要查閱第三欄小於10以下的資料,並只列出帳號與第三欄
複製代碼 代碼如下:
# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t \t"$3}'
註:查詢結果未顯示第一行資料,是因為我們雖然定義了FS=":" 但卻只能在第二行生效
想讀取第一行就需要BEGIN這個關鍵詞:
複製代碼 代碼如下:
# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "\t \t"$3}'
df:
比較兩個檔案的差異:
複製代碼 代碼如下:
# diff /etc/rc3.d/ /etc/rc5.d/
-------------------
Only in /etc/rc3.d/: K30spice-vdagentd
Only in /etc/rc5.d/: S70spice-vdagentd
-------------------
執行個體:
1。統計TCP串連狀態
複製代碼 代碼如下:
# netstat -na | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
/^tcp/
過濾出以tcp開頭的行,“^”為Regex用法,以...開頭,這裡是過濾出以tcp開頭的行。
S[]
定義了一個名叫S的數組,在awk中,數組下標通常從 1 開始,而不是 0。
NF
目前記錄裡域個數,預設以空格分隔,如上所示的記錄,NF域個數等於
$NF
表示一行的最後一個域的值,如上所示的記錄,$NF也就是$6,表示第6個欄位的值,也就是SYN_RECV或TIME_WAIT等。
S[$NF]
表示數組元素的值,如上所示的記錄,就是S[TIME_WAIT]狀態的串連數
++S[$NF]
表示把某個數加一,如上所示的記錄,就是把S[TIME_WAIT]狀態的串連數加一
結果就是顯示S數組中最終的數組值
例:S[TIME_WAIT]=最終值 S[TESTABLISHED]=最終值
END
for(key in S)
遍曆S[]數組
print key,”\t”,S[key]
列印數組的鍵和值,中間用\t定位字元分割,顯示好一些。
PS:關於正則,本站還提供了2款非常簡便實用的Regex線上工具供大家參考使用:
JavaScriptRegex線上測試載入器:http://tools.jb51.net/regex/javascript
Regex線上產生工具:http://tools.jb51.net/regex/create_reg