1 概述
通配符和正則表達式經常會引起混亂,本文兩者之間的區別進行比較。
通配符用于匹配文件名,shell在做PathnameExpansion時用到的。通配符是由shell解析的,比如find,ls,cp,mv等命令支持通配符查找文件名。
正則表達式元字符有字符匹配、匹配次數、位置錨定、分組。主要是處理文本里的內容,用來匹配文本里的字符串,針對文件內容的文本過濾工具里,大都用到正則表達式,如grep,sed,awk,vim, less,nginx,varnish等命令支持正則表達式。
2 通配符
2.1 常用通配符
通配符是由shell處理的(不是由所涉及到命令語句處理的,其實我們在shell各個命令中也沒有發現有這些通配符介紹), 它只會出現在命令的“參數”里(它不用在命令名稱里,也不用在操作符上)。當shell在“參數”中遇到了通配符時,shell會將其當作路徑或文件名去在磁盤上搜尋可能的匹配:若符合要求的匹配存在,則進行替換(路徑擴展);否則就將該通配符作為一個普通字符傳遞給“命令”,然后再由命令進行處理。
總之,通配符實際上就是一種shell實現的路徑擴展功能。在通配符被處理后, shell會先完成該命令的重組,然后再繼續處理重組后的命令,直至執行該命令。
shell提供轉義符有三種轉義符號,單引號,雙引號,和反向斜杠,讓通配符或者元字符變成普通字符,不需要使用特殊含義
需要說明的是:通配符看起來有點象正則表達式語句,但是它與正則表達式不同的,不能相互混淆。把通配符理解為shell特殊代號字符就可。
常用通配符,通配符的其他特殊字符,轉義字符如下表格
2.1 ?通配符例子
2.1.1 常用通配符例子
1、顯示/var目錄下所有以l開頭,以一個小寫字母結尾,且中間出現至少一位數字的文件或目錄
ll l*[[:digit:]]*[[:lower:]]
2、顯示/etc目錄下以任意一位數字開頭,且以非數字結尾的文件或目錄
ll [[:digit:]]*[^[:digit:]]
ll [0-9]*[^0-9]
3、顯示/etc/目錄下以非字母開頭,后面跟了一個字母及其它任意長度任意字符的文件或目錄
ll [^[:alpha:]][[:alpha:]]*
4、顯示/etc/目錄下所有以rc開頭,并后面是0-6之間的數字,其它為任意字符的文件或目錄
ls -d rc[0-6]*
5、顯示/etc目錄下,所有以.d結尾的文件或目錄
ls -d *.d
6、顯示/etc目錄下,所有.conf結尾,且以m,n,r,p開頭的文件或目錄
ls -ld [mnrp]*.conf 多了一個d 參數后就會只顯示文件夾,不顯示文件夾里的信息
7、只顯示/root下的隱藏文件和目錄
ls -Ad .*
ls -d .*[[:alnum:]]
8、只顯示/etc下的非隱藏目錄
ls -F | grep '/$'
ls -l? | grep '^d'
2.1.2 單引號和雙引號
單引號、雙引號用于用戶把帶有空格的字符串賦值給變量事的分界符。
[root@localhost sh]# str="Today is Monday"
[root@localhost sh]# echo $str
Today is Monday
如果沒有單引號或雙引號,shell會把空格后的字符串解釋為命令。
[root@localhost sh]# str=Today is Monday
bash: is: command not found
單引號和雙引號的區別。單引號告訴shell忽略所有特殊字符,而雙引號忽略大多數,但不包括三個符號$(美元符號)、\(反斜杠)、`(反向單引號)。
[root@localhost sh]# testvalue=100
[root@localhost sh]# echo 'The testvalue is $testvalue'
The testvalue is $testvalue
[root@localhost sh]# echo "The testvalue is $testvalue"
The testvalue is 100
2.1.3 反向單引號
這里再說一下反向單引號,再鍵盤左上角,和波浪號一起的符號。
在Linux中起著命令替換的作用,命令替換是指shell能夠將一個命令的標準輸出插在一個命令行中任何位置。
如下,shell會執行反引號中的date命令,把結果插入到echo命令顯示的內容中。
[root@localhost sh]# echo The date is `date`
The date is 2011年 03月 14日 星期一 21:15:43 CST
3 正則表達式
3.1 常用正則表達式
grep (global search regular expression(RE) and print out the line,全面搜索正則表達式并把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的擴展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它們把所有的字母都看作單詞,也就是說,正則表達式中的元字符表示回其自身的字面意義,不再特殊。linux使用GNU版本的grep。它功能更強,可以通過-G、-E、-F命令行選項來使用egrep和fgrep的功能。
grep的工作方式是這樣的,它在一個或多個文件中搜索字符串模板。如果模板包括空格,則必須被引用,模板后的所有字符串被看作文件名。搜索的結果被送到屏幕,不影響原文件內容。
grep可用于shell腳本,因為grep通過返回一個狀態值來說明搜索的狀態,如果模板搜索成功,則返回0,如果搜索不成功,則返回1,如果搜索的文件不存在,則返回2。我們利用這些返回值就可進行一些自動化的文本處理工作。
3.2 例子
1、顯示三個用戶root、sunny、tom的UID和默認shell
grep "^root\>\|^sunny\>\|^tom\>" /etc/passwd | cut -d: -f3,7
grep -E "^root\>|^sunny\>|^tom\>" /etc/passwd
grep -E "^(root|sunny|tom)\>" /etc/passwd | cut -d : -f3,7
2、找出/etc/rc.d/init.d/functions文件中行首為某單詞(包括下劃線)后面跟一個小括號
grep -oE "^[[:alnum:]_]+\(\)" /etc/rc.d/init.d/functions
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
echo /etc/rc.d/init.d/functions | grep -oE "[^/]+/?$"
非/開頭,最后是/可有可無,然后結尾,這個肯定是最后一個字段才是這樣的情況
4、使用egrep取出上面路徑的目錄名
echo /etc/rc.d/init.d/functions/ | grep -oE "^/.*/\<"
這道題不太清楚,最后一個位置錨定,/開頭,/<這個是位置錨定,用/最后的位置錨定
5、統計last命令中以root登錄的每個主機IP地址登錄次數
last | grep ^root | grep -oE "([0-9]{1,3}.){3}[0-9]{1,3}"|sort| uniq -c|sort -nr
6、利用擴展正則表達式分別表示0-9、10-99、100-199、200-249、250-255
echo {0..255} | grep -oE "\<[0-9]\>" |tr "\n" " "直接截取出對應數字在換成一行
echo {0..255} | grep -oE "\<[1-9][0-9]\>"
echo {0..255} | grep -oE "\<1[0-9]{2}\>"詞尾不錨定也可以
echo {0..255} | grep -oE "\<2[0-4][0-9]\>"
echo {0..255} | grep -oE "\<25[0-5]\>"
7、截取出ipv4地址
ifconfig | grep -oE "\<(([0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
8、顯示ifconfig命令結果中所有IPv4地址
ifconfig | grep -oE "\<([0-9]{1,3}\.){3}[0-9]{1,3}"
以下這個語句可以精確到每個位的范圍
ifconfig | grep -oE "\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
注意這里的點號要加反斜杠進行轉義。
9、將此字符串:welcome to magedu linux 中的每個字符去重并排序,重復次數多的排到前面
echo "welcome to magedu linux" | grep -oE [[:print:]]|sort|uniq -c|sort -r
4 區別對比
需要明確的是,通配符是用來匹配文件名,進行文件名的查找,而正則表達式是用來匹配文件里內容的,我們常用的grep命令,交給管道符之后使用grep已經不是匹配文件名了,這是對文件的操作,并不是匹配文件名。
不同點
相同點