Linux正規表達式
grep與正規表達式簡介
文本處理工具中的三劍客--grep、sed、awk
grep,grep是根據模式過濾文本,并将符合模式的行顯示出來,grep是一組工具集,包括了grep,egrep, fgrep。
sed,sed是stream editor,流編輯器,是以本質來說這是一個基于行文本編輯工具,也可以做過濾,但是如果用于做過濾的話,就有點大材小用了。
awk,Linux上的實作是gawk,awk其實是一個程式設計語言,它支援判斷,循環等過程式語言的基本特性,awk主要特性既不是過濾文本,也不是編輯文本,而是能夠将給定的資料以非常美觀的格式輸出的工具,是以他是一個文本報告生成器。
grep
grep是文本搜尋工具,根據使用者指定的"模式"對目标文本逐行進行比對檢查,列印比對到的行
- 模式:有正規表達式字元及文本字元所編寫的過濾條件
- 正規表達式:REGEXP,由一類特殊字元及文本字元所編寫的模式,這些特殊字元不表示字元字面意義,而是表示控制或者通配的功能
正規表達式的類型
正規表達式又分為兩類,基本正規表達式(BRE)和擴充正規表達式(ERE)
- BRE:grep預設情況下是支援基本正規表達式的
- ERE:egrep是用來支援擴充正規表達式,grep的-E選項也可以用來支援擴充正規表達式
fgrep表示不支援正規表達式。fast grep,如果支援正規表達式的話,必然要進行正規表達式解析,那就必然要耗費時間
grep的用法
# 基本文法
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
- OPTIONS,指令選項
- PATTERN,模式
- FILE,目标文本,可以是一個或者是多個
grep的常用選項
1.指定使用正規表達式類型的選項
注意:其實我們使用一個grep就可以對grep家族(grep/egrep/fgrep)的指令進行調用
- -E:使用擴充正規表達式,相當于egrep
- -F:不使用正規表達式,相當于fgrep
- -G:使用基本正規表達式,預設行為
- -P:使用perl正規表達式
2.指定正規表達式行為的選項
- -i:比對時,忽略字元大小寫
- --color=auto:grep預設情況下是不顯示比對上的字元,是以最好加一個顔色
- -v: 反向選擇,也就是說隻顯示沒有被模式比對到的整行内容
- -o:隻顯示被模式比對到的字元串
- -q:靜默模式,不輸出任何資訊,比如我們在寫腳本的時候,隻需要知道是否比對上了即可,不需要輸出,那麼就有必要用這個選項
**grep比對到了,那麼grep執行的狀态碼是0,沒有比對到,執行狀态碼是1
Title:将grep重命名,自己就不用每次都設定顔色了。
- -A:After-context,grep -A 2 root /etc/passwd:表示顯示passwd檔案中比對到了root的行,以及比對到的行之後的兩行(如果後面的行已經不夠了,盡量顯示)
- -B:Before-context,grep -B root /etc/passwd:表示顯示passwd檔案中比對到了root的行,以及比對到的行之前的兩行(如果前面的行不夠了,盡量顯示)
- -C:Context,grep -C root /etc/passwd:表示顯示passwd檔案中比對到了root的行,以及比對到的C前後兩行(盡量顯示)
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias grep='grep --color=auto'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
基本正規表達式BRE
BRE的元字元
元字元,是指不代表字元本身的意義,而是表示通配和控制。grep中正規表達式的元字元根據功能可以分為字元比對,比對次數,位置錨定和分組
如果在比對的模式中出現了元字元了,那麼就要用引号引起來,單引号表示強引用,雙引号為弱引号,是以雙引号引起來的話,裡面有變量也會被替換成變量的值,然後做比對。
1.字元比對
- . :比對任意單個字元;
- [] :比對指定字元範圍内的任意單個字元
- [^] : 取反,比對指定字元範圍外的任意單個字元
注意:可以使用的字元範圍有①字元集合:[:digit:], [:lower:], [:upper:], [:punct:];②特殊符号:[:space:], [:alpha:], [:alnum:];③數字和字母,是以我們在使用字元比對時,還需要加上元字元,例如:[[:alpha:]]表示比對字母
2.比對次數
比對次數用在字元比對後面,表示控制字元比對的次數
- *:*表示比對其前面的字元任意次,0到n次;例如:x*y,表示比對以y結尾,前面有0到n個x,預設情況下,正規表達式工作在貪婪模式下。*本身是不代表任意字元的,隻是代表任意次數,是以類似*y這樣是沒有意義的。這和glob中的*通配符的意義是不同的。glob中ll *.txt還是可以查詢到.txt結尾的檔案的
- \?:比對其前面的字元1次或0次(問号是在'',是以一定要用轉義字元将其轉義出來)。這也可以和glob作一個比較,在glob中是不用放到''内的,是以不用進行轉義
- \+:比對其前面的字元至少1次
- \{n\}:比對前面的字元n次,一定要是n次
- \{n,\}:比對前面的字元至少n次
- \{,n\}:比對前面的字元至多n次,即0到n次
\{m,n\}:比對其前面的字元至少m次,至多n次,({}必須加轉義字元)例如:grep 'a.{1,3}b'也就是說a和b之間最多可以3個a,最少需要出現1個a
**關于比對次數的例子
\\{1,\\} :最少重複一次,沒有上限 \\{0,3\\}:0-3次 \\{3\\}:固定的3次**
3.位置錨定
- ^:行首錨定,必須是寫在左側
- $:行尾錨定,必須寫在行尾
注意:如果^root$那麼表示這一行,必須隻能是root,另外^$表示是一個空行,^[[:space:]]*$表示比對空行或者是空白字元的行
- \< 或者 \b:詞首錨定,用于單詞模式的左側,
- \>或者\b:詞尾錨定,用于單詞模式的尾部,
- \:單詞錨定,例如:grep '<root>' /etc/passwd
4.分組
其中1表示:從左側起,第一個左括号以及與之比對的右括号之間的模式所比對到的字元
\(pattern\):表示這個pattern當做一個整體來看待,例如:grep '(root)+' /etc/passwd,比對passwd檔案中含有root字元串至少一次的行
這裡的分組和上面的單詞錨定有本質的差別,單詞錨定是root前後必須都是特殊字元,像//、空格、:等,而\(root\)+則表示root是不可分割的整體,而且其後面可以根據指定的比對次數表示連續的重複的出現root的情況
後向引用:引用前面的分組括号中模式所比對到的字元,不是模式本身。
分組括号中的模式所比對到的内容會被正規表達式引擎記錄于内部的變量中,這些變量在grep中被命名為:1,2,3...,在其他語言中可能會不一樣。
例如:(ab+(xy)),此時的1是ab+(xy),第一個左側括号到其結束的右括号,2是xy
擴充正規表達式元字元ERE
ERE的元字元
ERE中的元字元相容BRE中的元字元,不過BRE中需要使用\來轉義的元字元,在ERE中可以不用\了
- *:*表示比對其前面的字元任意次,0到n次;
- ?:比對其前面的字元1次或0次在擴充正規表達式中,可以不用使用\來進行轉義。
- +:比對其前面的字元至少1次
- {n}:比對前面的字元n次,一定要是n次
- {n,}:比對前面的字元至少n次
- {,n}:比對前面的字元至多n次,即0--n次
- {m,n}:比對其前面的字元至少m次,至多n次,({}必須加轉義字元)例如:grep 'a.{1,3}b'也就是說a和b之間最多可以3個a,最少需要出現1個a
\\{1,\\} :最少重複一次,沒有上限 \\{0,3\\}:0-3次 \\{3\\}:固定的3次**
- \< 或者 \b:詞首錨定,這裡的\是要保留的
- \>或者\b:詞尾錨定
- (pattern):分組這裡的\也可以不用
- 後向引用:後向引用這邊的1,2...還是一樣的
5.或者
a|b:表示比對a或者b
注意:C|cat:表示的是比對C或者cat,這種對稱形式的模式表示"或者"時,表示的是要麼比對左邊,要麼比對右邊;(C|c)at表示比對cat或者Cat