1盘榨、分組:將需要過濾的內(nèi)容規(guī)劃成一個整體硬霍,簡單理解就是把字符框選起來當(dāng)作一個整體進行過濾處理。
2坏快、分組可以進行嵌套边臼。
3、后向引用:通過 \序號 引用前面分組匹配出來的結(jié)果假消。
1柠并、分組:將需要過濾的內(nèi)容規(guī)劃成一個整體,簡單理解就是把字符框選起來當(dāng)作一個整體進行過濾處理富拗。
①臼予、假設(shè)需要過濾 appleappleapple 這 3 個連續(xù)的 apple 的單詞。首先編輯內(nèi)容文件 test.txt
[root@localhost ~]# vim test.txt
appleappleapple
~
~
~
:wq
- 要義一:grep -w 不能過濾沒有分隔符的字符串啃沪。
## grep -w 參數(shù)不能過 3 個 apple 單詞過濾出來
[root@localhost ~]# cat test.txt
appleappleapple
[root@localhost ~]# grep -w "apple" test.txt
[root@localhost ~]#
- 把內(nèi)容中的 apple 分隔開才可以用 grep -w 參數(shù)過濾單詞粘拾。
[root@localhost ~]# vim test.txt ## 編輯 test.txt
apple apple apple ## 空格分隔開 apple
~
~
~
:wq ## 保存
[root@localhost ~]# cat test.txt ## 查看 test.txt 文件內(nèi)容,apple 已經(jīng)隔開
apple apple apple
[root@localhost ~]# grep -w "apple" test.txt ## 分隔開的 apple 才可以用 -w 參數(shù)過濾單詞
apple apple apple
[root@localhost ~]#
- 要義二:對于需要過濾一定次數(shù)的字符串用 \{ 次數(shù) \} 進行次數(shù)的控制创千。那么缰雇,想要過濾連續(xù)的 appleappleapple。如果用 "apple\{ 3 \}" 原意上希望過濾連續(xù)出現(xiàn) 3 次的 apple追驴。實際上 \{ 3\} 只是過濾前面連續(xù)出現(xiàn)的字符 3 次械哟,也就是連續(xù)出現(xiàn) 3 次 e 的數(shù)據(jù)。
[root@localhost ~]# vim test.txt
appleappleapple
appleee ## 新增一條 appleee
~
~
~
:wq ## 保存
[root@localhost ~]#
[root@localhost ~]# cat test.txt
appleappleapple
appleee ## <--- 新增的內(nèi)容
[root@localhost ~]# grep "apple\{3\}" test.txt ## "apple\{3\}" 實際上是過濾前面的字符連續(xù)出現(xiàn) 3 次的數(shù)據(jù)
appleee ## 過濾了連續(xù)出現(xiàn) 3 次 e 的數(shù)據(jù)殿雪。
[root@localhost ~]#
- 要義三:如果需要過濾一個單詞整體出現(xiàn)多少次則需要用到分組暇咆。把希望處理的字符括起來就可以,如 (apple)丙曙,當(dāng)成一個整體爸业。后面跟上過濾的次數(shù)就可以根據(jù)括起來的字符這一整體進行過濾。
[root@localhost ~]# cat test.txt
appleappleapple
## \( \)亏镰,轉(zhuǎn)義括號 扯旷,\{ \} 轉(zhuǎn)義花括號
[root@localhost ~]# grep "\(apple\)\{1\}" test.txt ## 過濾 1 個 apple
appleappleapple
[root@localhost ~]# grep "\(apple\)\{2\}" test.txt ## 過濾 2 個 apple
appleappleapple
[root@localhost ~]# grep "\(apple\)\{3\\}" test.txt ## 過濾 3 個 apple
appleappleapple
[root@localhost ~]# grep "\(apple\)\+" test.txt ## 過濾 1 個以上 apple
appleappleapple
[root@localhost ~]#
\( \) 表示分組,\(apple\) 表示把 apple 字符串當(dāng)成一個整體索抓,而 \{3\} 則可以針對 apple 進行連續(xù)出現(xiàn)次數(shù)的過濾钧忽。
注:基礎(chǔ)正則的 ( ) 括號和 { }花括號需要用 \ 轉(zhuǎn)義某抓。
2、分組可以進行嵌套惰瓜。簡單理解就是分組內(nèi)含分組否副。
- 新增一個 banana 單詞。從單詞上看崎坊,除去開頭 b备禀,結(jié)尾 a。中間的 anan 是有規(guī)律且重復(fù)的內(nèi)容奈揍。所以曲尸,可以用分組來表達。
[root@localhost ~]# vim test.txt ## 編輯 test.txt
appleappleapple
banana ## 新增內(nèi)容
~
~
~
:wq ## 保存
[root@localhost ~]#
[root@localhost ~]# grep "\(b\(an\)\{2\}a\)\{1\}" test.txt
banana
- 應(yīng)用在多個 banana 上的情況男翰。
[root@localhost ~]# vim test.txt
appleappleapple
bananabananabanana ## 新增內(nèi)容
~
~
~
:wq
[root@localhost ~]# grep "\(b\(an\)\{2\}a\)\{3\}" test.txt
bananabananabanana
[root@localhost ~]#
3另患、后向引用:通過 \序號 引用前面分組匹配出來的結(jié)果。
③-①蛾绎、假設(shè)有 apple banana cherry damson apple banana cherry damson
這段話昆箕。
[root@localhost ~]# vim test.txt
apple banana cherry damson apple banana cherry damson
~
~
~
:wq
[root@localhost ~]# cat test.txt
apple banana cherry damson apple banana cherry damson
[root@localhost ~]#
- 如果想表達兩個 apple 之間的內(nèi)容∽夤冢可以用 grep "apple.*apple" test.txt鹏倘。
[root@localhost ~]# grep "apple.*apple" test.txt
apple banana cherry damson apple banana cherry damson
[root@localhost ~]#
③-②、另外一種方法是分組和后向引用顽爹,使用后向引用之前纤泵,一定要有分組。
[root@localhost ~]# grep "\(apple\).*\1" test.txt
apple banana cherry damson apple banana cherry damson
[root@localhost ~]#
- 后向引用是引用前面分組的的結(jié)果镜粤。從表達式分析 \(apple\).*\1捏题,首先把 apple 用 ( ) 括起來分組,作為一個整體肉渴。(基礎(chǔ)正則的 ( )括號需要用 \ 進行轉(zhuǎn)義)公荧。.* 代表任意字符,\1 代表引用第一個分組黄虱,這里第一個分組是 apple稚矿。所以 \1 也等同于 apple。
4捻浦、正如 \1 引用表達式的第一分組,那么 \2桥爽、\3...就是引用表達式的第二朱灿、第三...等等對應(yīng)的分組。
④-①钠四、test.txt 編輯測試內(nèi)容盗扒。
[root@localhost ~]# vim test.txt
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: banana
apple or banana or cherry or damson: cherry
apple or banana or cherry or damson: damson
~
~
~
:wq
[root@localhost ~]# cat test.txt
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: banana
apple or banana or cherry or damson: cherry
apple or banana or cherry or damson: damson
[root@localhost ~]#
④-②跪楞、把前段的 apple、banana侣灶、cherry 和 damson 進行分組甸祭,后段通過后向引用前面不同的分組,從而輸出對應(yīng)的行內(nèi)容褥影。通過此了解 \1池户、\2、\3凡怎、\4 引用前面的分組結(jié)果校焦。
[root@localhost ~]# cat test.txt ## 查看 test.txt 的內(nèi)容
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: banana
apple or banana or cherry or damson: cherry
apple or banana or cherry or damson: damson
## 通過不同的后向引用,輸出對應(yīng)的行內(nèi)容统倒。
[root@localhost ~]# grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\4" test.txt
apple or banana or cherry or damson: damson
[root@localhost ~]# grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\1" test.txt
apple or banana or cherry or damson: apple
[root@localhost ~]# grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\2" test.txt
apple or banana or cherry or damson: banana
[root@localhost ~]# grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\3" test.txt
apple or banana or cherry or damson: cherry
- 通過輸出進行分析:
- grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\1" test.txt 分析圖示寨典。
- grep "\(apple\).*\(banana\).*\(cherry\).*\(damson\).*\2" test.txt 分析圖示。
- grep "\(apple\).\(banana\).\(cherry\).\(damson\).\3" test.txt 分析圖示房匆。
- grep "\(apple\).* \(banana\).* \(cherry\).* \(damson\).* \4" test.txt 分析圖示耸成。
④-③、詞首和詞尾相呼應(yīng)浴鸿。假設(shè)有一需求墓猎,輸出詞首和詞尾相同的行。延用以上的測試內(nèi)容赚楚。在已知詞首的情況下可以在表達式中寫上具體的詞首內(nèi)容毙沾,然后通過后向引用分組內(nèi)容。情況如下:
[root@localhost ~]# cat test.txt
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: banana
apple or banana or cherry or damson: cherry
apple or banana or cherry or damson: damson
[root@localhost ~]#
[root@localhost ~]# grep "^\(apple\).*\1$" test.txt
apple or banana or cherry or damson: apple
④-④宠页、假設(shè)不知道一段內(nèi)容中有多少詞首和詞尾相同的行左胞。這種情況下并不能像以上的例子把具體內(nèi)容進行分組,沒有分組就不能后向引用举户。這時可以用 .* 進行分組來表達詞首的內(nèi)容烤宙,再用后向引用分組的結(jié)果。情況如下:
④-④-①俭嘁、修改一下 test.txt 文檔內(nèi)容躺枕。
[root@localhost ~]# vim test.txt
apple or banana or cherry or damson: apple ## 詞首和詞尾是相同的字符串
apple or banana or cherry or damson: banana
cherry or apple or banana or damson: cherry ## 詞首和詞尾是相同的字符串
apple or banana or cherry or damson: damson
~
~
~
:wq! ## 保存并退出
④-④-②、grep "^\(.*\) .* \1$" test.txt 輸出詞首詞尾相同的行供填。
[root@localhost ~]#
[root@localhost ~]# cat test.txt
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: banana
cherry or apple or banana or damson: cherry
apple or banana or cherry or damson: damson
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# grep "^\(.*\) .* \1$" test.txt
apple or banana or cherry or damson: apple
cherry or apple or banana or damson: cherry
[root@localhost ~]#
[root@localhost ~]#
④-④-③拐云、注意事項,用 .* 進行詞首詞尾匹配時需要留意內(nèi)容的格式近她。比如叉瘩,^\(.*\) 后面沒有空格 和 \1$ 前面沒有空格,它的輸出效果如下:
- 因為 .* 代表所有(包含空)粘捎。^\(.*\) 是從頭到尾所有內(nèi)容的意思薇缅。通過下圖可以直觀看到效果危彩。
- 如上述,表達式 ^\(.*\) .* \1$ 中的分組是輸出整行的內(nèi)容泳桦,當(dāng) ^\(.*\) 分組后面沒有空格隔開時汤徽,后向引用就是引用了分組的結(jié)果。所以灸撰,輸出是全部內(nèi)容標(biāo)紅谒府。并不是預(yù)期的只輸出詞首詞尾一致的行。
④-④-④梧奢、實現(xiàn)輸出詞首詞尾一致的行狱掂。需要考慮的是把詞首區(qū)域的單詞進行分組。然后亲轨,通過后向引用詞尾的單詞來和詞首分組的結(jié)果進行對比趋惨,如果一致就過濾輸出。通過觀察文本格式惦蚊,不難發(fā)現(xiàn)詞首 apple 后面跟了一個空格器虾。不妨試試 ^\(.*\) 后用空格隔開的效果。
- 從以上圖片可以看到 ^\(.*\) 后用空格隔開輸出的效果是字符串后面有空格的都標(biāo)紅蹦锋。這樣的就知道怎樣去找到詞首兆沙。之所以這么多標(biāo)紅,是因為 grep 的貪婪模式莉掂。凡是單詞后有空格的都標(biāo)紅葛圃,稍微改動一下能更清晰的理解。
[root@localhost ~]# vim test.txt
apple:or banana or cherry or damson apple ## 詞首 apple 后跟 : 號憎妙,詞尾 apple 前刪除 : 號
apple or banana or cherry or damson: banana
cherry or apple or banana or damson: cherry
apple or banana or cherry or damson: damson
~
~
~
:wq ## 保存并退出
- "^(.*):" :意思是 : 號前的任意字符串都是詞首库正,通過修改過后的第一行不難發(fā)現(xiàn)通過首個單詞后跟符號進行分隔,可以找到詞首的內(nèi)容厘唾。
- 至此就是通過 "^(.*) " 匹配后續(xù)分隔符來找詞首的方法褥符。
④-④-⑤:詞尾作為后向引用時,需不需要結(jié)合文本格式進行輸入抚垃?
- 后向引用 \1$ 前有空格和沒有空格效果喷楣,從輸出效果看并沒有什么不同。
- 修改 test.txt 文件鹤树,增加三行內(nèi)容铣焊。詞尾分別是 xxapple、applexx魂迄、xxapplexx粗截,再看看情況。
[root@localhost ~]#
[root@localhost ~]# vim test.txt
apple or banana or cherry or damson: apple
apple or banana or cherry or damson: xxapple ## 增加內(nèi)容捣炬,詞尾 xxapple
apple or banana or cherry or damson: applexx ## 增加內(nèi)容熊昌,詞尾 applexx
apple or banana or cherry or damson: xxapplexx ## 增加內(nèi)容,詞尾 xxapplexx
apple or banana or cherry or damson: banana
cherry or apple or banana or damson: cherry
apple or banana or cherry or damson: damson
~
~
~
:wq
- 通過詞尾不同格式的輸出得出以下的情況湿酸。
- 由此可見婿屹,詞尾作為后向引用還是匹配文本內(nèi)容格式輸出的效果較為嚴謹一些。
5推溃、后向引用嵌套分組如何區(qū)分第一分組(\1)昂利、第二分組(\2)?铁坎?蜂奸?
⑤-①、以 bananabanana 為測試數(shù)據(jù)硬萍。
⑤-②扩所、先通過兩個表達式查看一下輸出結(jié)果。
分別是 :grep "\(b\(an\)\).*\1" 和 grep "\(b\(an\)\).*\2"
⑤-③朴乖、后向引用嵌套分組的順序取決于分組時左括號的順序祖屏。從表達式 \(b\(an\)\) 分析:
⑤-④买羞、\1 后向引用嵌套分組圖示袁勺。
⑤-⑤、\2 后向引用嵌套分組圖示畜普。
6期丰、擴展:為什么說后向引用是分組的結(jié)果?吃挑?钝荡?
⑥-①、測試用例:applexxabble儒鹿。當(dāng) grep "\(a...e\).*\1" 時化撕,\(a...e\) 是 a開頭,e結(jié)尾约炎,中間任意 3 位字符的字符串植阴,分組代表 apple。雖然 apple 和 abble 的開頭和結(jié)尾都是一樣圾浅,位數(shù)也是一樣掠手。而 \1 后向引用 \(a...e\) 時則沒有輸出結(jié)果。這是因為 apple 和 abble 并不一樣狸捕,\1 后向引用 \(a...e\) 時并不是引用 a 開頭喷鸽,e結(jié)尾,中間任意 3 個字符的字符串灸拍。而是必須要和分組的結(jié)果相一致才能后向引用成功做祝。
[root@localhost ~]# echo "applexxabble" | grep "\(a...e\).*\1"
[root@localhost ~]#
⑥-②砾省、把 abble 改為 apple,\1 才能起到后向引用的效果混槐。
root@localhost ~]# echo "applexxapple" | grep "\(a...e\).*\1"
applexxapple
7编兄、或 符號 \|。(如 a \| b(a 或者 b)声登。a \| A(a 或者 A)
⑦-①狠鸳、測試數(shù)據(jù)。
⑦-②悯嗓、輸出 a 開頭或這 b 開頭的行件舵。
⑦-③、輸出 a 開頭或 y 結(jié)束的行脯厨。
⑦-④铅祸、輸出含有 pp 或 an 或 rr 字符的行。
⑦-⑤俄认、輸出 a 開頭(后面任意字符)或 b 開頭(后面任意字符)的行个少,
- test.txt 文件增添一些內(nèi)容:
[root@localhost ~]# vim test.txt
almond 杏仁
apple 蘋果
apricot 杏子
arbutus 楊梅
banana 香蕉
bennet 水楊梅
bergamot 佛手柑
berry 槳果
betelnut 檳榔
cherry 櫻桃
damson 洋李子
~
~
~
:wq ## 保存
--------------------------------------------------------------------
[root@localhost ~]#
[root@localhost ~]# cat test.txt
almond 杏仁
apple 蘋果
apricot 杏子
arbutus 楊梅
banana 香蕉
bennet 水楊梅
bergamot 佛手柑
berry 槳果
betelnut 檳榔
cherry 櫻桃
damson 洋李子
[root@localhost ~]#
- grep "^\(a\|b\).*" test.txt 過濾 a 和 b 開頭,后面任意字符的行眯杏。
- 不要寫成 grep "^ a\|^b.*" test.txt,這樣的意思是 a 開頭 或者 b 開頭后面任意字符的意思岂贩。
⑦-⑥茫经、 如有一需求是過濾 apple 或 bpple。grep "^a\|bpple" test.txt 實際輸出時 a 開頭的字符串萎津,并不是 apple 或 bpple卸伞。
- 這里應(yīng)該用分組锉屈,grep "^\(a\|b\)pple" test.txt荤傲,^ 符號后用分組把 a \| b 括起來才表示 apple 或 bpple。
⑦-⑦遂黍、 如有一需求是過濾相同的字符串,忽略首字母大小寫俊嗽。
- 新增首字母大寫的 Apple
[root@localhost ~]# vim test.txt
almond 杏仁
apple 蘋果
Apple 蘋果 ## 新增首字母大寫的 Apple
apricot 杏子
arbutus 楊梅
banana 香蕉
bennet 水楊梅
bergamot 佛手柑
berry 槳果
betelnut 檳榔
cherry 櫻桃
damson 洋李子
~
~
~
:wq ## 保存并退出
- 同樣的雾家,a 和 A 進行分組。
- 如果不把 a 和 A 進行分組绍豁,過濾條件的意思是過濾 a 開頭 或者 APPLE 的字符串芯咧。