因為在之前說過grep指令支持正則表達式,因此在次使用grep來進行學習
一、正則表達式基礎
1、查找特定的字符串
為grep的基本功能,之前已經說過了,主要是通過指令grep 'strname' filename
2、使用[]來查找集合字符
[]代表的是某一個字符,而其中使用的式限定該字符的規則,其中使用[^]代表與某規則相反,如下說是^e的結果就是啥也看不到,相應的規則表達形式在后續總結。

3、行首與行尾字符^$
為了在已經篩選完成的結果中進一步篩選,如列出查找的字符在句首的行顯示出來,那么可以使用^來進行篩選,與上面的[^]存在區別,為了進一步說明區別grep -n '^[^a-zA-Z]' log_complex.txt 的意思為找到不以字母開頭的行,第一個^代表的就是行首,第二個[^]代表的就是取反,在[]內部和外部的^的意思是不一樣的

對於查找詞在句尾的時候可以使用$來進行查找,但是如下所示windows下的斷行符並不僅僅隱藏$結尾,其隱藏的為^M$,但是這個^M不是字符不可進行匹配操作,不可使用查找,而在linux下為.$,在linux中.字符有特殊的意義,因此需要使用轉義字符\.$

4、任意一個字符.與重復的字符*
.(小數點):代表一定有一個任意字符。
*(星號):代表重復前面的字符0到n次,為組合形態。注意這是正則表達式。
在之前講過shell的通配符,其中:
* :匹配任意多個字符(包括零個或一個)與正則表達式存在區別
? :匹配任意一個字符(不包括零個)
例如使用grep 'g*g' text.txt查找包含以g開頭和以g結尾的字符串,如下所示,實際上缺少了一個’.‘,應當的輸入為grep 'g.*g' text.txt,所有問題的根源在於*正則表達式可以表示前一個字符0個元素,相當於直接消除了前面的元素。使用’.‘在’*‘之前相當於沒有消除前一個字符。



5、使用連續RE字符范圍
4中找出的是任意多的字符,那么需要找到限定的字符數量該如何操作?如上面的找2~5個o在gd之間。此時就需要使用范圍限定字符{},由於{}在shell中有特殊意義,因此需要使用轉義字符\配合使用,如在上述的結果中查找在字符gd之間包含兩個以上的o的goo*d形式的行的操作為: grep -n 'go\{2,5\}'d text.txt
上下限可以不指明表示不少於和不多於,例如查找在字符gd之間包含不少於2個o的行可以使用 grep -n 'go\{2,\} text.txt'

6、總結
正則表達式的特殊字符與一般命令行輸入的通配符是不一樣的!
^word:待查找的字符串(word)在行首。
word$:帶查找的字符串(word)在行尾。
. :一定代表一個任意字符
*:代表0~n個與前一個字符重復的字符
[list]:表示從集合集的RE字符中找到想要選取的字符
[n1-n2]:從集合集的RE字符中找到想要選取的字符范圍,但是要明確語系的,不然范圍的選擇會出現問題
[^list]:表示從集合的RE字符中找到不要的字符串和范圍。
\{start,end\}:start或者end可以省略一個,若接該內容的最后一個字符為o,則表示限定o字符出現的次數為start與end之間。
在list的選擇中會由於編碼語系的影響而造成一定的問題,因為有的編碼是a,b,c...z但是有的卻是a,A,b,B,c,C....z,Z,因此為了避免編碼問題帶來的集合的錯選,有一些特殊的符號可以使用
[:alnum:]:0-9,A-Z,a-z
[:aipha:]:A-Z,a-z
[:blank:]:空格和鍵值
[:cntr:]:代表鍵盤上的控制按鍵,包括del、contrl等
[:digit:]:代表數字
[:graph:]:除了空格與tab鍵意外的其他所有按鍵
[:lower:]:a-z
[:punct:]:代表標點符號
[:upper:]:大寫的A-Z
[:xdigit:]:代表16進制的數字類型,包括0-9,a-z,A-Z
[:print:]:任何可以被打印出來的字符

注意下面的錯誤,一定在外面另加一個[],也就是說需要[[:pattern:]],下面是查找一個包含16進制字符的以9結尾的行。

查詢滿足s(標點)t的行

使用print標准查找
![]()
使用上述方法查詢在etc文件夾下的鏈接文件

7、sed工具
sed的作用可以對標准輸入進行處理,包括替換刪除、新增、選定特定行的功能。可以看到sed類似於filter能夠對輸入流進行編輯,過濾。
![]()

語法規則是:sed [-nefr] [動作]
-n :在一般的sed用法中,所有的標准輸入都會被列在屏幕上,但是在該模式下,只有經過特殊處理的才會被顯示
-e :直接在命令行模式上進行sed的動作編輯
-f:直接講sed的動作寫在一個文件內,-f filename 則是可以執行filename內的sed動作
-r :sed 的動作支持的是拓展型正則表達式的語法(默認式基礎的正則表達式語法)
-i:直接修改讀取的文件內容,而不是在屏幕輸出
動作說明: n1,n2 function 代表在n1 和n2之間執行function
function:
a:增加,后面可以接字符串,這些字符會在新的一行出現。
c:替換,后面可以接字符串,這些字符串可以替換n1與n2之間的所有的行。
d:刪除,通常不接任何內容。
p:打印內容
i:插入,i后面可以接字符串,這些字符串會插入當前行的上一行。
s:替換,可以進行替換工作,通常這個動作可以搭配正則表達式。
使用function d 進行刪除8-9行的內容。

同樣的刪除10行以后的所有行,其中$代表最后一行,所有的操作並不會影響到原始文件,因為其僅僅能夠處理流數據。

在某一行進行添加使用a,可以使用\進行多行的輸入,一定到有空格!a是在制定行后,i為指定行前。

將2-4行替換為NO 2-4 number字符串,實際上可以看到行號都沒有了,直接替換了。

打印選定的行使用function p 但是問題在於-n 安靜模式,實際上不使用-n有很大的輸出影響,即為選定的行會重復輸出。


在進行文本的替換使用‘s/要被替換的內容/新的字符串/g’

使用組合替換刪除,使用grep選出所需要操作的行,使用seed對選出的行進行刪除等操作

之前的所有操作都不具備更改原始文件的能力,為了增加sed對原始文件的修改能力使用-i參數,例如 sed -i 's/test/change/g' text.txt ,關鍵在於使用-i需要后接文件,也不難以理解,因為你畢竟需要改動源文件。
在使用-i 進行添加a的時候會另起一行,為了能夠在行首或者行尾添加內容還是需要使用替換模式s

二、拓展正則表達式
之前的正則表達式都需要處理完一個操作后才能接另一個操作,例如grep -v 'string1' filename|grep -v 'string2' filename十分冗長,因此有可以講這兩句合並,合並的語句為 egrep -v 'string1|string2' filename這樣就可以達到相同的目的,由於grep默認是不支持拓展正則表達式的,因此要使用egrep來支持拓展正則表達式。
cat log_complex.txt|grep -v 'Epoch'|grep -v 'This fpr'

cat log_complex.txt|egrep -v 'Epoch|This fpr'

拓展的正則表達式的其他支持的操作有:
+:重復一個或者一個以上的前一個RE字符,注意與基本正則表達式*的區別。
?:重復0個或者1個前一個RE字符。
|:使用或的方式找出數個字符串
():找到組字符串
()+:多個重復組的判別
egrep 'go+d' text.txt :順利的找到了符合要求的行,但是沒有找gd

egrep 'go?d' text.txt:找到了gd和god,使用.對比一下區別能夠看到區別


