Linux之正則表達式的應用
正則表達式作為Linux入門的重要符號語言,是基礎中的基礎,當然,也是初學者人人頭疼的一座山。在此略做小結,如果有幸幫了哪位入門同仁的困惑,也算不枉此篇。
此篇舉例僅基於grep或egrep進行,一來剛學習至此,二來盡求此點清晰全面。本文重點問講解如何使用正則表達式,畢竟解決問題是目的。行文或有不周之處,還望各位賜教。
在這之前,我們先來簡要回顧下grep的用法。
grep -[acinv]
--color=auto | 將匹配的結果著色顯示 |
-v | 反向匹配 |
-i | 忽略大小寫 |
-n | 顯示的結果前增加行號 |
-c | 僅顯示匹配到結果的行的數量 |
-b | 在輸出結果前打印當前行在輸入中的字符偏移量 |
-o | 僅顯示最後正則表達式匹配到的字符串 |
-q | 靜默模式,不輸出任何信息,此作用等同於&> /dev/null |
-A # | 顯示關鍵字行及向後#行(#為數字) |
-B # | 顯示關鍵字行及向前#行 nmap -v -sP 172.17.252.0/24 |grep-B1 "Host is up"|grep for |cut -d" " -f5 |wc -l (掃描IP段,並統計在線IP數量) |
-C # | 顯示關鍵字向前#行,當前行,及向後#行 |
-e | e 關鍵字1 -e 關鍵字2 實現多個選項間的邏輯or關系 grep -e ‘cat‘ -e ‘dog‘ file(顯示有cat或dog的行) |
-w | 匹配整個單詞,即基於單詞過濾 |
-E | 使用擴展正則表達式 或egrep 擴展的正則表達式egrep 或grep -E支持無轉移字符\,但指範圍時還需要表示為\<\>、\b\b等 |
-F | 不使用正則表達式 或 fgrep |
——更多grep選項請到http://os.51cto.com/art/201108/285119.htm
下面是一些正則表達式的簡單介紹。
1.字符匹配
. 匹配任意單個字符
[] 匹配指定範圍內的任意單個字符
[^] 匹配指定範圍外的任意單個字符
[:alnum:] 字母和數字,或[0-9a-zA-Z]
[:alpha:] 代表任何英文大小寫字符,亦即[a-zA-Z]
[:upper:] 大寫字母,或[A-Z]
[:lower:] 小寫字母,或[a-z]
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的範圍廣)
[:cntrl:] 不可打印的控制字符(退格、刪除、警鈴...)
[:digit:] 十進制數字 [0-9]
[:xdigit:]十六進制數字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 標點符號
2.匹配次數
* 匹配前面的字符任意次,包括0次
.* 任意長度的任意字符
\? 匹配其前面的字符0或1次
\+ 匹配其前面的字符至少1次
\{n\} 匹配前面的字符n次
\{m,n\} 匹配前面的字符至少m次,至多n次
\{,n\} 匹配前面的字符至多n次
\{n,\} 匹配前面的字符至少n次
3.位置錨定
^ 行首錨定,用於模式的最左側
$ 行尾錨定,用於模式的最右側
^PATTERN$ 用於模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 詞首錨定,用於單詞模式的左側(無需與下面的左右同時引用)
\> 或 \b 詞尾錨定;用於單詞模式的右側
\<PATTERN\> 匹配整個單詞 或\bPATTERN\b
4.分組
\(\) 將一個或多個捆綁在一起,當作一個整體進行處理,如:\(Gintoki\)\+
分組括號中的模式匹配到的內容會被正則表達式引擎記錄於內部的變量中,這些變量的命名方式為:\1.\2,\3,....
\1表示從左側起第一個左括號以及與之匹配右括號之間的模式所匹配到的字符
示例:\(saber\+\(archer\)*\)
\1:saber\+(archer\)*
\2:archer
後項引用:引用前面的分組括號中的模式所匹配字符,而非模式本身。即引用的為實際字符,不是可變的變量
或:\|
示例:s\|a:a或b C\|cat:C或cat \(C\|c\)at:Cat或cat
5.常配合使用的相關命令
sort 排序。默認數字從小到大,字符從A-z
-r 執行反方向(由上至下)整理(Z-a,數字從大到小)
-n 執行按數字大小整理
-f 選項忽略(fold)字符串中的字符大小寫
-u 選項(獨特,unique)刪除輸出中的重復行
-t c 選項使用c做為字段界定符
-k X 選項按照使用c字符分隔的X列來整理能夠使用多次
head 頭顯示
-n #(#為數字)顯示前#行
-c # 顯示前#個字節
tail 尾顯示
-n # 顯示後#行
-c # 顯示後#個字節
cut 按列截取
-d 指定分割符
-f#[,#,#,...] 選取第#列,可多個
tr 轉換和刪除字符
-s ‘‘ 把連續重復的字符取一個表示
-d ‘‘ 刪除‘‘內所有字符
-t ‘‘ ‘‘ 第一個字符集對應字符轉化為第二字符集
tr -t ‘A-Z‘ ‘1-9‘不加-t時第9-26個字符都轉化為9,-t保持原形
-c ‘‘ 反向,即只保留‘‘內字符
熱身完畢,接下來我們沖個涼(來看看一些經常用到的命令)。
1、找出ifconfig “網卡名”命令結果中本機的IPv4地址(head -n 2為截取輸出前兩行,tail -n 1為截取輸出最後一行,tr -s " "為將連續的多個空格保留為一個,cut -d: -f4為以列截取,以:為間隔截取第四列)
ifconfig |head -n 2 |tail -n 1|tr -s " " : |cut -d: -f4
2、查出分區空間使用率的最大百分比值(df顯示分區信息,tr -s ‘ ‘ %為將所有的連續空格保留一個,並將其替換為%,sort -t% -k5 -n以%為間隔符,按第5列數字大小排序)
df|tr -s ‘ ‘ %|sort -t% -k5 -n|tail -n 1|cut -d% -f5
3、查出用戶UID最大值的用戶名、UID及shell類型
cat /etc/passwd |cut -d: -f1,3,7|sort -n -t : -k 2|tail -n 1
4、查出/tmp的權限,以數字方式顯示(stat file查看文件時間戳)
stat /tmp| head -n 4|tail -n1|cut -d/ -f1|cut -d‘(‘ -f2
stat -c %a /tmp/
stat /tmp|head -n 4|tail -n1|tr -dc [1-7];echo -e ‘\n
5、統計當前連接本機的每個遠程主機IP的連接數,並按從大到小排序
netstat -tun | grep ESTAB|tr -s " " : |cut -d: -f6 |sort -nr |uniq -c
1、顯示/proc/meminfo文件中以大小s開頭的行(要求:使用兩
種方法)
cat /proc/meminfo |grep ^‘\(S\|s\)‘
cat /proc/meminfo |grep ^[Ss]
cat /proc/meminfo |grep -i "^s"
cat /proc/meminfo|grep -e ^s -e ^S
cat /proc/meminfo|grep "^s\|^S"
cat /proc/meminfo|grep "^[s\|S]"
2、顯示/etc/passwd文件中不以/bin/bash結尾的行
cat /etc/passwd |grep -v ‘/bin/bash$‘
grep -v "/bin/bash$" /etc/passwd
3、顯示用戶rpc默認的shell程序
cat /etc/passwd |grep ^‘\<rpc\>‘|cut -d: -f7
grep -w "^rpc" /etc/passwd | cut -d : -f7
4、找出/etc/passwd中的兩位或三位數
cat /etc/passwd | grep ‘\<[0-9]\{2,3\}\>‘ 突出顯示,沒有取出數字,實際上不符合題意
cat /etc/passwd |grep -o "\<[0-9]\{2,3\}\>"只取出數字
5、顯示CentOS7的/etc/grub2.cfg文件中,至少以一個空白字符開頭的且後面存非空白字符的行
cat /etc/grub2.cfg |grep"^[[:space:]]\+[^[:space:]]"
6、找出“netstat -tan”命令的結果中以‘LISTEN’後跟任意多個空白字符結尾的行
netstat -tan|grep "\<LISTEN\>[[:space:]]*$"
7、顯示CentOS7上所有系統用戶的用戶名和UID
cat /etc/passwd |cut -d: -f1,3|grep ‘\<[0-9]\{1,3\}\>$‘
8、添加用戶bash、testbash、basher、sh、nologin(其shell為/sbin/nologin),找出/etc/passwd用戶名同shell名的行
cat /etc/passwd | grep "\(^.*\)\>.*\/\1$"
9、利用df和grep,取出磁盤各分區利用率,並從大到小排序
df |grep ^/dev/sd |grep -o "\b[[:digit:]]\{1,3\}\b%"|sort-rn
1、顯示三個用戶root、mage、wang的UID和默認shell
cat /etc/passwd |cut -d: -f3,7 |egrep^‘\<mage\>|\<root\>|\<wang\>‘
cat /etc/passwd|grep -E "^(root|wang|mage)\>"|cut -d :-f3,7
cat /etc/passwd|grep -E -w "^(root|wang|mage)"|cut -d :-f3,7
2、找出/etc/rc.d/init.d/functions文件中行首為某單詞(包括下劃線)後面跟一個小括號的行
cat /etc/rc.d/init.d/functions |grep ‘^[_[:alpha:]]*[(]‘
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
echo /etc/rc.d/init.d/functions|egrep -o \([[:alpha:]]\)+$
4、使用egrep取出上面路徑的目錄名(這個題目開始我是想用)
echo /etc/rc.d/init.d/functions|egrep -o \(^/.*/\) 截取//之間所有字符
echo /etc/rc.d/init.d/functions|egrep -o \(^/.+/\) 以/開始,以/結束
echo /etc/rc.d/init.d/functions|egrep -o \(.+/\) 以任意字符開始,以/結束
5、統計last命令中以root登錄的每個主機IP地址登錄次數
last|egrep root.*[.]|tr -s ‘ ‘|cut -d‘ ‘ -f3|sort |uniq -c
6、利用擴展正則表達式分別表示0-9、10-99、100-199、200-249、250-255
echo {0..300}|egrep -o "\<[0-9]{,1}\>"
echo {0..300}|egrep -o "\<[0-9]{2}\>"
echo {0..300}|egrep -o "\<1[0-9]{2}\>"
echo {0..300}|egrep -o "\<2[0-4][0-9]\>"
echo {0..300}|egrep -o "\<25[0-5]\>"
7、顯示ifconfig命令結果中所有IPv4地址
ifconfig |egrep [.].*[.]|tr -d [:alpha:]
8、將此字符串:welcome to magedu linux 中的每個字符
去重並排序,重復次數多的排到前面
echo "welcome to magedu linux "|egrep -o .|sort |uniq -c|sort -r
echo /etc/rc.d/init.d/functions|egrep -w \([[:alpha:]]\)+$
Linux之正則表達式的應用