正則表達式與grep

 

 


+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
張賀,多年互聯網行業工做經驗,擔任過網絡工程師、系統集成工程師、LINUX系統運維工程師
我的網站:www.zhanghehe.cn
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-git


grep與正則表達式

不管是生活、仍是學習,想要成爲搜索的高手,正則表達式都是繞不過的一道檻,利用正則表達式能夠迅速找到咱們想要的任何信息。正則表達式

正則表達式的理解與其說須要時間的沉澱,不如是說是須要思考的沉澱和屢次的練習。shell

當咱們學習時正則、擴展正則時不能拘泥於"城池"的得失,要關注大局,學完比學好更重要!express

0、grep

DISCRIPTION:vim

grep:global search regular expression and print out the line(根據正則表達式進行全局搜索並打印輸出行)centos

grep是文本搜索工具,是根據用戶指定的模式對目標文本進行匹配檢查,並打印匹配到的行,注意是打印匹配文件的所在行,而不是打印匹配到的目標文本。bash

所謂模式就是由正則表達式及文本字符構成的過濾條件。網絡

SYNOSIS:app

grep [OPTIONS] PATTERN [FILE...]運維

grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

默認grep沒有語法着色,其語法着色是經過別名--color=auto生效的。

OPTIONS:

-i:ignorecase:忽略大小寫

-o:僅顯示匹配的到的字符串自己

-v:invert-match,顯示不能被模式匹配的行

-E: 支持擴展正則,egrep與其等同

-q:--quiet,--slient,靜默模式,即不輸出任何信息(腳本當中會用到,省了&>/dev/null

-A #:after,後#行

-B #:before,前#行

-C #:context,先後各#行

一、基礎

特殊字符

-:表明上一個目錄

[root@N2 zhanghe]# cd
[root@N2 ~]# cd $OLDPWD
[root@N2 zhanghe]# 
[root@N2 zhanghe]# cd /etc/
[root@N2 etc]# cd -
/root/zhanghe

.:當前目錄

//清空當前目錄
[root@N2 zhanghe]# rm -rf ./*

..:上一級目錄

[root@N2 tmp]# cd ..
[root@N2 /]#

~:家目錄,cd默認就是回家目錄

[root@N2 zhanghe]# cd ~
[root@N2 ~]#

xargs,分組,輸入重寫向,也常與find連用,有將字符流轉換爲可用路徑的含義。

[root@N2 zhanghe]# echo {1..10} > test2.txt
[root@N2 zhanghe]# cat test2.txt
1 2 3 4 5 6 7 8 9 10
//3個一組
[root@N2 zhanghe]# xargs -n 3 <test2.txt
1 2 3
4 5 6
7 8 9
10

引號相關

不加引號可支持通配符,沒法將內容變成總體,含義和雙引號同樣

[root@N2 zhanghe]# touch a b
[root@N2 zhanghe]# touch "a b"
[root@N2 zhanghe]# ll
-rw-r--r-- 1 root root 0 Feb 10 18:28 a
-rw-r--r-- 1 root root 0 Feb 10 18:28 a b
-rw-r--r-- 1 root root 0 Feb 10 18:28 b

單引號:所見即所得

[root@N2 zhanghe]# zh=zhanghe
[root@N2 zhanghe]# echo '$zh'
$zh

雙引號:特殊符號會被解析

[root@N2 ~]# zh=zhanghe
[root@N2 ~]# echo '$zh'
$zh
[root@N2 ~]# echo "$zh"
zhanghe

反引號:引用命令,可將字符流轉換爲路徑;等同於$()。

//將字符流轉換爲生效路徑,與xargs意義相似
[root@N2 ~]# mv `find /etc -name *tion` /tmp
[root@N2 ~]# ls /tmp
application  motion

//host=$(echo zhanghe)等同於host=`echo zhanghe`
[root@N2 ~]# vim test.sh 
#!/bin/bash
host=$(echo zhanghe)
echo $host
[root@N2 ~]# sh test.sh
zhanghe

二、通配符

通配符的做用是幫助咱們查找文件名的,經常與find -namels連用,這一點要記住,而正則表達式用來找文件內容的。

*:匹配0或多個字符,看清是0和多個字符,也就是說也能夠沒有,好比:

//文件名當中只要包含zh便可
[root@N2 zhanghe]# touch hellozh zhhello hezhllo zh
[root@N2 zhanghe]# ls *zh*
hellozh  hezhllo  zh  zhhello

?:僅表明一個字符。

[root@N2 zhanghe]# touch zhanghe zhangghe zhanggghe
[root@N2 zhanghe]# ls zhang?he
zhangghe

[abcd]:匹配中括號裏面的任意一個字符,看準是一個。

[root@N2 zhanghe]# touch a b c d e f g
[root@N2 zhanghe]# ls [abcd]
a  b  c  d

[a-z]:[1-9]與之相似,匹配中括號裏面的任意一個字符,a-z表明26個小寫字母,看準是一個。

[root@N2 zhanghe]# touch a b c d e f g
[root@N2 zhanghe]# ls [a-d]
a  b  c  d
[root@N2 zhanghe]# ls [a-z]
a  b  c  d  e  f  g

[!a-z]:[!1234]與之相似,!可用^代替,匹配取反中括號裏面的任意一個字符,[a-d]同理。

[root@N2 zhanghe]# touch a b c d e f g
[root@N2 zhanghe]# ls [!a-d]
e  f  g

三、正則表達式元字符

字符匹配

.任意單個字符

[]:範圍內的任意單個字符。

[^] :範圍外的任意單個字符。

//匹配以r開頭中間必須是兩個字符結尾是t的字符串
[root@N2 ~]# grep 'r..t' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
//r..t這個模式中的.包括空格嗎?包括,例如:
[root@N2 ~]# cat test.txt 
ro t
[root@N2 ~]# grep 'r..t' test.txt  #在終端選中結果後,會發現空格也是着色的,說明把空格也匹配了
ro t

經常使用字符集:

[:digit:]:全部數字

[:lower:]:全部小寫字母

[:upper:]:全部大寫字母

[:alpha:]:全部字母(包括大小寫)

[:alnum:]:全部字母(包括大小寫)和數字

[:punct:]:全部標號符號

[:space:]:注意,僅表示一個空格

//匹配r開頭中間任意一個小寫字母結尾是t的行,注意[:lower:]僅表明字符集,不能單獨使用,只有外面再加一箇中括號才表示這些字符集裏面的一個。
[root@N2 ~]# grep 'r[[:lower:]]t' /etc/passwd

//與上一個例子類似,只不過這是取反
[root@N2 ~]# grep 'r[^[:digit:]]t' /etc/passwd
/匹配/r和t之間有兩個字母的行,這樣寫太麻煩,因此要有次數匹配
[root@N2 ~]# grep 'r[[:alpha:]][[:alpha:]]t' /etc/passwd

次數匹配

用在要指定其出現次數的字符的後面,用於限制其前面字符出現的次數,默認工做於貪婪模式。

*:匹配其前面的字符任意次,0次、1次 ,2次……,屢次。

.*:匹配任意長度的任意字符

\?:匹配前面的字符0次或1次,即其前面的字符是無關緊要的。

\+:匹配其前面的字符1次或屢次,即其前面的字符要出現至少1次

\{m\}:匹配其前面的字符m次

\{m,n\}:匹配其前面的字符至少m次,至多n次

\{0,n\}:至多n次

\{m,\}:至少m次

值得說一說的是*:

//表示只要有y出現便可,x能夠沒有,也能夠有任意次
 grep 'x*y' test.txt 
 
 //任意單個字符,無關緊要,並且能夠有屢次,因此會匹配任意長度的任意字符,包括特殊字符什麼的,並且因爲其貪婪性,若是對一個文檔使用.*的話,裏面的全部都會被匹配上,在終端選中後便可驗證。
 grep '.*' test.txt

位置錨定

位置錨定之行錨定:

^:行首錨定,寫在模式的最左邊

$:行尾錨定,用於模式的最右邊

^pattern$:用pattern來匹配整行

^$空白行

^[[:space:]]*$:空行或包含空白字符的行

位置錨定之單詞錨定:

這些的單詞指是非特殊字符組成的連續字符串都稱爲單詞。

\<或\b:詞首錨定,用於單詞模式的左側

\>或\b:詞尾錨定,用於單詞模式的右側

\<pattern\>:匹配完成單詞

分組引用

xy*表示y能夠有也能夠沒有,可是咱們把xy這兩個字母當成一個總體呢?怎麼辦?這時候就要用到分組引用,其實就是用小括號將要引用的字符串括起來,當成一個總體看待。

NOTE:分組括號中的模式匹配的內容會被正則表達式引擎自動記錄於內部的變量中,這些變量爲:

1:模式從左側起,第一個左括號以及與之匹配的右括號之間的模式所匹配到的字符。

2:模式從左側起,第二個左括號以及與之匹配的右括號之間的模式所匹配到的字符。

括號可嵌套,不要交叉,括號有意義,因此要轉義。

後向引用:引用前面的分組括號中的模式所匹配到的字符

練習

//顯示/etc/passwd文件中不以/bin/bash結尾的行
[root@N2 ~]# grep -v "/bin/bash$" /etc/passwd

//找出/etc/passwd文件中的兩位數或三位數
[root@N2 ~]# grep "\b[[:digit:]]\{2,3\}\b" /etc/passwd
[root@N2 ~]# grep "\<[0-9]\{2,3\}\>" /etc/passwd


//找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以致少一個空白字符開頭、後後面非空白字符的行。
[root@N2 ~]# grep "^[[:space:]]\+.*[^[:space:]]" /etc/grub2.cfg

//找出netstat –tan命令的結果中以LISITEN後跟0、1或多個空白字符結尾的行。
[root@N2 ~]# netstat -tan | grep "LISTEN[[:space:]]*$"

四、擴展的正則表達式

擴展的正則表達式大體上基本的正則表達式是同樣的,就是有一些細節上的區別:

  1. 次數的匹配的斜線沒有了

  2. 分組引用當中支持」或者「

//找出/proc/meminfo文件中,全部以大寫或小寫s開頭的行,至少有三種實現方式:
[root@N2 ~]# grep -i "^s" /proc/meminfo 
[root@N2 ~]# grep "^[sS]" /proc/meminfo
[root@N2 ~]# egrep "^(s|S)" /proc/meminfo

//顯示當前系統上root、centos或user1用戶的相關信息
[root@N2 ~]# egrep "^(root|centos|user1)\b" /etc/passwd

//找出/etc/rc.d/init.d/funcitons文件中某單詞後跟一個小括號的行
[root@N2 ~]# egrep -o "[_[:alnum:]]+\b\(\)" /etc/rc.d/init.d/functions

//使用echo命令輸出一個絕對路徑,使用egerp取於基名
echo /etc/passwd | egrep -o "[^/]+/?$"
echo /etc/passwd/ | egrep -o "[[:alnum:]]+/?$"


//取目錄名
[root@kk ~]# echo /etc/passwd/ | egrep -o '^/[^/]+'
/etc
echo etc/passwd | egrep -o "^/?[^/]+/{1}"
echo etc/passwd/ | egrep -o "^/?[[:alnum:]]+\b/?"

//找出ifconfig當中的1-255之間的數
ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-5]{2})\>"

//找出ip地址(使用grep找IP很差用):
[root@N2 ~]# ifconfig eth0 | grep -E -o "([0-9]{1,3}\.){3}[0-9]{1,3}"
192.168.80.59
255.255.255.0
192.168.80.255

//添加bash用戶,找到/etc/passwd文件當中用戶名與shell名的行
[root@N2 ~]# egrep "^([^:]+\b).*\1$" /etc/passwd
 egrep '(^.*):.*\1$' /etc/passwd
相關文章
相關標籤/搜索