文章目錄
正則表達式和grep、vim、awk、sed等的關係:
正則表達式是一種方法,相當於一種工藝,grep等命令相當於是一個具體的加工機器,機器在加工產品的時候,採用這種方法。
三者的效率:grep>sed>awk
1. 通配符(globbing)
常用通配符:
* 代表 匹配0個或者多個字符
?代表匹配1個字符
[…] :匹配範圍內任意1個字符,例如[az]、[a-z]、[a\-z]
[^…]: 匹配範圍外任意1個字符,表示取反
{}:組合匹配,touch a{1,3,5} touch b{1..10} touch {a,b,c}_{1,2,3}
例:
[0-9] 代表數字
[abcd123]代表取中括號裏的任意一個字符
[a-Z] 代表大小寫字母
[0-Z]代表數字0-9和所有的大小寫字母
正則表達式裏通配符和shell裏面的通配符的區別:
- shell裏面的通配符:用在bash裏面;
- 正則裏面的通配符:用在真正的命令裏面。
2. grep
grep全稱通用正則表達式分析程序(global research regular expression and printing)。
其實,grep是一個過濾命令,根據特定的正則表達式來過濾文本里的內容。
grep是根據某個模式進行匹配文件裏的一行一行的數據去處理的,如果有匹配的行,就會將整行輸出到屏幕上。
grep用的時候模式要用雙引號""引起來!!!
用途:使用正則表達式搜索文本,並把匹配的行打印出來
格式:grep [選項] 模式 目標文件
模式其實就是一個公式,裏面有字母+數字+特殊符號,組合成一個正則表達式,表達出某個含義。
常用選項:
-v:invert,反轉查找,輸出與模式不相符的行;
-An:after-context,同時顯示符合條件行的下面n行;
-Bn:before-context,同時顯示符合條件行的上面n行;
-Cn:同時顯示符合條件行的上面n行和下面n行;
-E:extended regular,支持擴展正則表達式;
-o:only-matching,僅顯示匹配的字符串;
-f:根據文件內容進行匹配;
-a:以文本文件方式搜索,不忽略二進制的數據;
-c:計算找到的符合行的次數;
-i:ignore-case忽略大小寫;
-n:line-number,順便輸出行號;
-P "\t" --》得到Tab鍵 --》使用perl語言的正則語法,支持\t表示table鍵,\s表示空白。
2.1 linux系統支持的三種形式的grep命令
Linux系統支持三種形式的grep命令,通常將這三種形式的grep命令稱爲grep命令族,這三種形式具體爲:
- ls /bin/*grep
- fgrep:不支持正則表達式,快速搜索簡單模式,按照字符串的字面意思進行匹配嗎,相當於grep -F
- grep:可以使用基本正則表達式搜索
- egrep:可以使用基本和擴展正則表達式搜索,相當於grep -E
3. 正則表達式
正則表達式是一個指定文本模式的標準Unix 語法。
使用特殊元字符實現複雜的搜索問題;
元字符(meta characters)是用來闡釋字符表達式意義的字符,簡言之,元字符就是描述字符的字符,它用於對字符表達式的內容、轉換及各種操作信息進行描述。
正則表達式是由一串字符和元字符構成的字符串,簡稱RE(Regular Expression)。
基本正則表達式和Unix兼容;
擴展正則表達式增加了一些新的元字符。
正則表達式由下列元素構成 :
- 普通字符,a、b 、1、2
- 通配符,與文件名通配符不是一回事
- 修飾符:”*” ”?”等
- 錨點:以什麼開頭、以什麼結尾。
正則裏的通配符:
- “.”:表示一定有一個任意字符
例:a…b :代表ab之間有三個字符。
- 方括號表達式:一個文字字符域
[abc] :a或者b或者c中的一個。
[^abc] :不是abc其中的一個。
[0-9]、[a-z]、[A-Z] : 數字、小寫、大寫。
- 域表達式和字符類
考慮到不同的編碼方案推薦使用字符類方式(此類方法不常用,以被上面②方式代替!)。
[:alnum:] -字母數字混排 等同於[0-Z]
[:digit:] -數字 等同於[0-9]
[:lower:] -小寫字母 等同於[a-z]
[:upper:] -大寫字母 等同於[A-Z]
[:space:] -空白字符,空格、TAB、換行符等
通用修飾符(理解爲通配符即可)
- 問號:表示0個或者1個前面的字符(0或1個)(擴展)
例:ab?c 代表沒有b或者只有一個b,即等同於ac、abc。
- 星號:表示>=0個前面的字符
例:ab*c 代表沒有b或者多個b,即等同於ac、abc、abbc、abbbc......
- +:表示1個或者多個前面的字符(>=1)
例:ab+c 代表 一個b或者多個b,即等同於abc、abbc、abbc......
- {n}:表示n個前面的字符(前面的字符出現了n次)
例:ab{2}c 代表b出現了兩次,即等同於abbc。
- {n,m}:表示n個到m個前面的字符。
例:ab{2,4}c 代表2個到4個b,即等同於abbc、abbbc、abbbbc。
- .* :點代表任意一個,星號表示前面的0個或多個,即等同於所有字符。
錨點搜索
- “^”:表示以什麼開頭行
例 ^aa 代表以aa開頭的行。
- 美元符:表示以什麼結尾的行
例 bash$代表以bash結尾的行。
- \<:表示詞首部。作用等同於\b
例 \bwubing 代表以wubing開頭的行。
- \>:表示詞尾部。作用等同於 \b
例 wubing\b 代表以wubing結尾。
- \< abc >:表示abc這個單詞 等價於 \babc\b
例 \<wubing\> 代表wubing這個單詞。
grep在界定單詞的時候,默認使用的分隔符是空白。
3.1 擴展正則表達式
egrep、awk和Perl等Linux工具還支持正則表達式擴展出來的一些元字符,這些元字符如下表所示:
- ?:匹配0個或1個在其之前的那個普通字符
- +:匹配1個或多個在其之前的那個普通字符
- ( ):表示一個字符集合
- | :表示’或’,匹配一組可選的字符
正則表達式分組
①“?”、”*”、”+”默認只能修飾前面一個字符
②利用圓括號( )可以實現多個字符分組。
例 f(oo)* :因爲oo括起來了,所以把oo看成"一個字符",即f、foo、foooo......
③在圓括號中利用”|”實現或者的功能
echo foooeee | egrep --color "(oo|ee){2}"
echo foooeee | egrep --color "(oo|ee){1}"
轉義元字符
egrep ‘cat.' /etc/aa
egrep ‘cat\.' /etc/aa
正則表達式與通配符匹配的區別:
- 正則表達式只在少數搜索和替換文本命令中使用;
- 文件名匹配在bash中匹配文件名;
- 都使用”*”、”?”但意義不一樣;
- 正則表達式元字符要放在引號內,避免bash Shell解釋。
4. IP的正則
4.1 ip地址的類別
簡單來講分爲三類:
- A類網絡的IP地址範圍爲:1.0.0.1-126.255.255.254;
- B類網絡的IP地址範圍爲:128.1.0.1-191.255.255.254;
- C類網絡的IP地址範圍爲:192.0.1.1-223.255.255.254
4.2 ip地址的正則
寫ip地址正則時的方法:需要按個位(1位)、十位(2位)、百位(3位)
顯示文件中的所有A類地址:(1-126)
"\b([1-9]|[1-9][0-9]|1[01][0-9]|12[0-6])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ){3}\b"
解析:
先寫的個位,十位,百位先寫的100-119,再120-126;
0-255,先0-9,再10-99,100-199,200-249,最後250-255
顯示文件中的所有B類地址:(128-191)
"\b(12[89]|1[3-8][0-9]|19[01])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) ){3}\b"
顯示文件中的所有C類地址:(192-223)
"\b(19[2-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]) ) {3}\b"
匹配email地址:
egrep "[0-Z._]+@[0-Z]+\.[a-Z]+"
匹配HTTP URL:
egrep "^http://([0-Z]+\.){2}[a-Z]{2,3}"
egrep --color "http://(.*\..*){2}" --》網址至少有兩個點!(適用所有網址)
5. shell中的特殊字符
- :冒號
內置的空命令,返回值爲0–》while : - ;分號
連續運行命令 - | 管道
前面命令的標準輸出作爲後面命令的標準輸入
正則中表示或者 - &
將命令放到後臺執行
表示標準輸出和標準錯誤輸出 - &&
前面命令執行成功才執行後面的命令 - ||
前面命令執行不成功才執行後面的命令 - 井號
表示註釋 - ? 問號
通配符中表示任意1個字符
正則表達式中表示0個或者1個前面的字符 - 星號
通配符中表示0個到多個任意字符
正則表達式中表示0個或者多個前面的字符
算術運算中的乘法 - !驚歎號
將命令或者條件表達式的返回值取反
執行歷史命令
vi或者ftp中執行外部shell命令
間接應用變量 --》${!b} - $ 美元符號
取變量的值
正則表達式表示行尾 - \ 反斜槓
單字符轉義 - 大於號
輸出重定向
條件測試中的大於號 - 小於號
輸入重定向
條件測試中的小於號 - = 等號
變量賦值
條件測試中的等號 - 加號
算術運算中的加號
正則表達式中1個或多個前面的字符 - >>
輸出重定向追加
<<
here document - - 減號
算術運算中的減號
命令的選項
上一次工作目錄
通配符和正則表達式中表示範圍[a-z]
tar -cvf - /home | tar -xvf - 表示輸出流或輸入流 - ’ ’ 單引號
解決變量賦值空格的問題
阻止shell替換 - " " 雙引號
解決變量賦值空格的問題
阻止shell部分字符替換,對$、!等無效 - `` 反引號
命令行替換 - % 百分號
算術運算中的模運算
vi中替換操作中表示所有行 - () 單圓括號
子shell中執行命令,會繼承父shell的變量
括起數組元素 - (()) 雙圓括號
算術運算
整數比較測試 - [] 單方括號
通配符和正則中表示匹配括號中的任意一個字符
條件測試表達式
數組中下標括號 - [[]] 雙方括號
字符串比較測試 --》不能比較小數!比較小數要用bc計算機–》echo “4.5>5.5”|bc ,返回值爲0,假的 - . 句點號
正則中表示任意1個字符
當前shell執行腳本命令
表示當前目錄 - {} 大括號
通配符擴展 abc{1,2,3}
正則表達式中表示範圍
匿名函數{cmd1;cmd2;cmd3} &> /dev/null
括起變量名${abc}a - / 正斜槓
算術運算中的除法
根目錄或路徑分割符 - ^
在[^abc]通配符中表示取反
在正則表達式中表示以什麼開頭
6. 練習
1.新建/lianxi目錄,複製/etc/passwd到當前目錄下。
2.查找出當前passwd文件中以ftp開頭或者mail開頭的行,在屏幕輸出。
3.查找出當前passwd文件中首行不是以r、m、f開頭的行,在屏幕輸出。
4.查找出當前passwd文件中以bash結尾的行。
5.查找出/etc/login.defs文件中的有效行(不顯示空行和註釋行)。
6.查找出/var/log/messages文檔中有16個字母的單詞。
7.查找/etc/passwd文件裏用戶名包含liu同時使用bash的用戶。
8.查找/etc/ssh/sshd_config文件裏的有效行。
9.查找/etc/ssh/sshd_config文件裏的包含連續2個數字的行。
10.查找出包含特殊字符的行。
11.查找出不包含數字的行。
12.查找出/var/log/messages裏的ip地址出來。
13.寫一個正則來表示出下面的網址,例如:
http://www.baidu.com
http://www.sina.com
http://www.163.com
http://www.12306.cn
http://www.qillu.edu
14.寫一個表示郵箱的正則,例如:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
15.C類ip地址的正則表達式
section1:範圍在192-223之間
section2和section3和section4範圍:0-255之間
例如:193.168.23.1
16.監控/var/log/secure文件,統計出ssh錯誤連接本機次數超過十次的ip地址,拒絕這個ip地址再ssh連接過來(將這個ip地址寫入到/etc/hosts.deny黑名單,/etc/hosts.allow是白名單)。
答案:
1.新建/lianxi目錄,複製/etc/passwd到當前目錄下。
mkdir /lianxi
cd /lianxi
cp /etc/passwd .
2.查找出當前passwd文件中以ftp開頭或者mail開頭的行,在屏幕輸出。
cat passwd|grep "^ftp|^mail"
3.查找出當前passwd文件中首行不是以r、m、f開頭的行,在屏幕輸出。
cat passwd|grep -v "^r|^m|^f"
4.查找出當前passwd文件中以bash結尾的行。
cat passwd|grep "bash$"
5.查找出/etc/login.defs文件中的有效行(不顯示空行和註釋行)。
cat /etc/login.defs|egrep -v "^$|^#"
6.查找出/var/log/messages文檔中有16個字母的單詞。
cat /var/log/messages|egrep "\<[0-Z]{16}\>"
7.查找/etc/passwd文件裏用戶名包含liu同時使用bash的用戶。
cat passwd|egrep "^[0-Z]*liu[0-Z]*" | egrep "bash"
或
cat /etc/passwd|egrep "^.*liu.*:x:"|egrep "bash"
或
cat passwd|egrep "^[0-Z_]*liu.*bash$"
8.查找/etc/ssh/sshd_config文件裏的有效行。
cat /etc/ssh/sshd_config|egrep -v "^$|^#"
9.查找/etc/ssh/sshd_config文件裏的包含連續2個數字的行。
cat /etc/ssh/sshd_config|egrep "\b[0-9]{2}\b"
10.查找出包含特殊字符的行。
cat /etc/ssh/sshd_config|egrep "[^0-Z]" --》包含特殊字符(^在[]裏面,表示取反)
11.查找出不包含數字的行。
cat /etc/passwd|grep -v ".*[0-9].*"
12.查找出/var/log/messages裏的ip地址出來。
cat /var/log/messages | egrep "\b([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ){3}\b"
13.寫一個正則來表示出下面的網址,例如:
http://www.baidu.com
http://www.sina.com
http://www.163.com
http://www.12306.cn
http://www.qillu.edu
[root@liupeng lianxi]# cat dizhi.txt
http://www.baidu.com
http://www.sina.com
http://www.163.com
http://www.12306.cn
http://www.qillu.edu
[root@liupeng lianxi]# cat dizhi.txt|egrep --color "http://(.*\..*){2}"
http://www.baidu.com
http://www.sina.com
http://www.163.com
http://www.12306.cn
http://www.qillu.edu
[root@liupeng lianxi]#
14.寫一個表示郵箱的正則,例如:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
PS:用戶名最大16位。
[root@liupeng lianxi]# cat youxiang.txt
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[root@liupeng lianxi]# cat youxiang.txt|egrep "\b[0-Z._]{1,16}+@[0-Z]+\.[a-Z]+\b"
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[root@liupeng lianxi]#
15.C類ip地址的正則表達式
section1:範圍在192-223之間
section2和section3和section4範圍:0-255之間
例如:193.168.23.1
[root@liupeng lianxi]# cat ipip.txt
193.168.23.1
10.10.10.1
192.168.12.12
123.123.123.123
[root@liupeng lianxi]# cat ipip.txt|egrep "\b(19[2-9]|2[01][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\b"
193.168.23.1
192.168.12.12
[root@liupeng lianxi]#
16.監控/var/log/secure文件,統計出ssh錯誤連接本機次數超過十次的ip地址,拒絕這個ip地址再ssh連接過來(將這個ip地址寫入到/etc/hosts.deny黑名單,/etc/hosts.allow是白名單)。
#!/bin/bash
while true
do
cat secure|egrep "Failed passwd"|egrep -o "\b192(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}\b"|sort|uniq -c|sort -nr >secure.txt
deny=$(cat /etc/hosts.deny|egrep "^sshd:192(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"|awk -F: '{print $2}')
echo $deny >deny_ip.txt
cat secure.txt|while read times IP
do
if (( $times>=2 ))
then
if ! grep $IP deny_ip.txt &>/dev/null
then
echo "sshd:$IP" >>/etc/hosts.deny&&echo "$IP has been written to /etc/hosts.deny"
fi
fi
done
sleep 1
done