正則表達式RE以及grep、awk和sed工具的用法詳解

1.什么是正則表達式

通俗的來說,正則表達式就是處理字串的方法,他是以行為單位來進行字串的處理行為, 正則表達式通過一些特殊符號的輔助,可以讓使用者輕易的達到“搜尋/刪除/取代”某特定字串的處理程序!正則表達式基本上是一種“表達式”, 只要工具程序支持這種表達式,那么該工具程序就可以用來作為正則表達式的字串處理之用。 例如 vi, grep, awk ,sed 等等工具,因為她們有支持正則表達式, 所以,這些工具就可以使用正則表達式的特殊字符來進行字串的處理。但例如 cp, ls 等指令并未支持正則表達式, 所以就只能使用 Bash 自己本身的通配符而已。

2.特殊符號以及RE字符

1.特殊符號
特殊符號 代表的含義
[:alnum:] 代表所有的大小寫英文字符和數(shù)字,即0-9 A - Z a-z
[:alpha:] 代表任意英文大小寫字符,即A-Z a-z
[:lower:] 代表小寫英文字符,即a-z
[:upper:] 代表大寫英文字符 ,即A-Z
[:digit:] 代表數(shù)字,即0-9
[:blank:] 代表 空格鍵或者Tab鍵
[:cntrl:] 代表鍵盤上所有的控制按鍵,如:CR、LF、Tab、Del等等
[:graph:] 代表除了空格鍵與Tab鍵之外的其它鍵
[:print:] 代表的是標點符號,如:' " ! ? ; # $ 等
[:space:] 代表任何能產(chǎn)生空白字符的按鍵,如:空格鍵,Tab,CR等等
[:xdigit:] 代表16進位的數(shù)字類型,包括:0-9,A-F,a-f的數(shù)字與字符

注意:前五條是常用的,其它一般不怎么用或者能用其它方式代替

2.特殊符號的示例

我們?nèi)ゾW(wǎng)上找一些數(shù)據(jù)來做實例

Hello! / Hi!
Good-bye, "Mike".
See you tomorrow.
It’s time for class.
Open your books and turn to page 20.
Could you say it again? 
Where’s the company? 
Which is the right size? 
Do you know where I’ve put my glasses? 
Is this your pen? I found it under the desk. 
Which is your bag? 
The one on your right. 
Are these books all yours? 
She must be a model, isn’t she? 
I really don’t known.
#I have no idea about it.
What’s your family name?
Rose, let me introduce my friend to you.
Nice to meet you, too.
toooooot 
What day is it today?
It’s January the 15th, 1999.
It’s the year of 1999.
However, this dress is about $ 3183 dollars.
我們將數(shù)據(jù)寫入一個文件里面
[root@localhost tmp]# vim test.text

開始匹配

[root@localhost tmp]# grep "[:alnum:]" test.text         #我們不能直接使用這些特殊符號
grep: 字符類的語法是 [[:space:]],而非 [:space:]
[root@localhost tmp]# grep "[[:alnum:]]" test.text        #我們需要用[]將其括起來
在這里插入圖片描述
3.RE字符及用法
RE字符 含義與用法示例
^ 含義:待匹配的在行首
[root@localhost tmp]# grep -n '^#' test.text      #匹配到以#開頭的行,并打印出行號
-n 參數(shù)表示顯示行號
在這里插入圖片描述
RE字符 含義與用法示例
$ 含義:待匹配的在行尾
[root@localhost tmp]# grep -n '!$' test.text      #匹配到以#開頭的行,并打印出行號
在這里插入圖片描述
RE字符 含義與用法示例
. 含義:一個任意字符
[root@localhost tmp]# grep -n 'e.e' test.text      
#匹配到的字符串可以是(ere)(eve),就是兩個e中間一定有且僅有一個其它字符,空字符也算。
#但不能是(ee) 如:See you tomorrow.  See雖然有兩個e,但是不符合就沒有出現(xiàn)
在這里插入圖片描述
RE字符 含義與用法示例
\ 含義:轉(zhuǎn)義字符,將特殊符號的特殊意義去掉
[root@localhost tmp]# grep -n '\$' test.text     
#    $   本來是匹配結(jié)尾的但是這里轉(zhuǎn)義就能匹配到
在這里插入圖片描述
RE字符 含義與用法示例
* 含義:將前面的一個字符重復(fù)零次到無窮次
[root@localhost tmp]# grep -n 'to*' test.text   
#  匹配到單個t(零次o) 匹配到too (多次o)  
在這里插入圖片描述
RE字符 含義與用法示例
[] 含義:[]表示匹配到里面其中一個字符
[root@localhost tmp]# grep -n 'o[nmt]' test.text  
# [nmt]代表n或m或t 所以會匹配到(on)(om)(ot)  
在這里插入圖片描述
[root@localhost tmp]# grep -n '[0-9]' test.text  
#[0-9]就相當于[0123456789]   
在這里插入圖片描述
RE字符 含義與用法示例
[^] 含義:表示匹配到除了里面之外的字符
[root@localhost tmp]# grep -n 'on[^e]' test.text 
#[^e] 表示除了e之外其它字符都可以即匹配不到one
#空字符也算
在這里插入圖片描述
RE字符 含義與用法示例
{n,m} 含義:前一個字符重復(fù)n到m次
[root@localhost tmp]# grep -n 'to\{1,3\}' test.text 
#重復(fù)o 一到三次
#要跟* 區(qū)分 *表示重復(fù)零次到無窮多次
在這里插入圖片描述

在這里插入圖片描述

3.grep

1.grep一些能跟正則搭配的參數(shù)
-A   n      把匹配成功行之后的n行也同時列出。 A 就是 after 的首字母就是之后的意思
-B   n      把匹配成功行之前的n行也同時列出。B 就是 before 的首字母就是之前的意思
-C  n   把匹配成功行的前后n行也同時列出。
-o          只顯示匹配到的字符
-c          統(tǒng)計數(shù)量    (一般是跟其它參數(shù)一起用)
-n          顯示行號     (前面說過了)
-l          只要文件名   
2.gerp的擴展正則

用擴展正則必須用egrep 或者grep -E

RE字符 含義與用法示例
+ 含義:前一個字符重復(fù)一次或一次以上
? 含義:前一個字符重復(fù)零次或一次
| 含義:表示或者
() 含義:群組字串
()+ 含義:前一個群組字串重復(fù)一次或一次以上
這里面+  和 ?  我就不多說了,注意要比較和* 的區(qū)別
而 |  的用法也特別簡單比如:
 [root@localhost tmp]# echo "tooooabsdsadooo"  | grep -E 'too|ab'     #表示匹配too或者ab
tooooabsdsadooo             #too  和 ab  將被標紅
[root@localhost tmp]# echo "goodaaaglad"  | grep -E 'g(oo|la)d'          #表示匹配到good或者glad
goodaaaglad                  #good和glad將被標紅
[root@localhost tmp]# echo "goodgabcabcabcglad"  | grep -E 'g(abc)+g'  #是匹配到gabcabcabcg
goodgabcabcabcglad        #找的是以g開頭g結(jié)尾,中間是一個以上的abc

寫出匹配日期格式 YYYY-MM-DD 的正則表達式(要仔細琢磨)

[root@localhost tmp ~]# echo "2019-12-30" |grep -E '[1-9][0-9]{3}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))'
2019-12-30
[root@localhost tmp ~]# echo "1919-12-30" |grep -E '[1-9][0-9]{3}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))'
1919-12-30

正則高級部分: 貪婪|非貪婪(了解就好)
貪婪 就是盡可能的多匹配
非貪婪 就是盡可能的少匹配,只需要在一些表示量詞(就是次數(shù))的后面加上 ?, 比如: .*? +?
grep 或者 egrep 默認都是貪婪模式,不支持非貪婪模式。
要想實現(xiàn)非貪婪需要使用 -P 參數(shù),這會使用 Perl 語言環(huán)境的正則

在這里插入圖片描述

4.awk

1.awk簡介

awk的處理文本和數(shù)據(jù)的方式是這樣的,它逐行掃描文件,從第一行到最后一行,尋找匹配的特定模式的行,并在這些行上進行你想要的操作。如果沒有指定處理動作,則把匹配的行顯示到屏幕上,如果沒有指定模式,則所有被操作所指定的行都被處理。

2.awk用法

awk [options] 'commands' filenames
awk [options] -f awk-script-file filenames -f 表示從腳本文件中讀取awk命令
options:
-F 對于每次處理的內(nèi)容,可以指定一個子定義的分隔符,默認的分隔符是空白字符(空格或 tab 鍵 )
command:

BEGIN{}             處理匹配到內(nèi)容之前的動作
{}                          處理匹配到內(nèi)容之中的動作
END{}                   處理匹配到內(nèi)容之中的動作
3.工作原理

(1)awk是一行一行處理的,每次處理時,使用一行作為輸入,并將這一行賦給內(nèi)部變量0,以換行符結(jié)束 (2)每行會被分隔符分成多個字段,每個字段存儲在已編號的變量中,從1開始,最多達100個字段
(3)初始時,F(xiàn)S賦為空白字符,所以默認為以空格為分隔符
(4)awk打印字段時,將以內(nèi)置的方法使用 print 函數(shù)打印,awk 在打印出的字段間加上空格。這個空格是內(nèi)部的一個變量 OFS 輸出字段的分隔符, 逗號 , 會和 OFS 進行映射,通過 OFS 可以控制這個輸出分隔符的值。
(5)awk輸出之后,將從文件中獲取另一行,并將其存儲在$0中,覆蓋原來的內(nèi)容,然后將新的字符串分隔成字段并進行處理。該過程將持續(xù)到所有行處理完畢

4.與字段有關(guān)的內(nèi)部變量
$0 : awk變量 $0 保存當前正在處理的行內(nèi)容
NR : 當前正在處理的行是 awk 總共處理的行號。
FNR: 當前正在處理的行在其文件中的行號。
NF :每行被處理時的總字段數(shù)
$NF: 當前處理行的分隔后的最后一個字段的值
FS : 字段分隔符,默認空格
OFS : 輸出字段分隔符,默認是一個 空格
ORS 輸出記錄分隔符, 默認是換行符.
[root@localhost tmp ~]# awk 'BEGIN{FS=":"} {print $NF}' /etc/passwd     #以:(冒號)為分隔符,輸出每一行的最后一個字段的值
[root@localhost tmp]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2,$3,$4}' /etc/passwd
root+++x+++0+++0                  #輸出時以+++隔開
[root@localhost tmp]# awk 'BEGIN{ORS="  "} {print $0}' /etc/passwd #將文件的所有行合并為一行
5.awk模式和動作

awk語句是由模式和動作組成的
模式可以是正則表達式,比較表達式等,而動作一般都是打印print
1.正則表達式:

awk '/正則表達式/'     filename      整行匹配   /正則表達式/  或 !/正則表達式/ 或 $0 ~ /正則表達式/
awk '字段 ~ /正則表達式/'     filename      某一字段匹配 字段 ~ /正則表達式/ 或 字段 !~ /正則表達式/
[root@localhost tmp]# awk -F: '/alice/' /etc/passwd      #只要有anlice就行
[root@localhost tmp]# awk -F: '$NF !~ /alice/' /etc/passwd      #最后一個字段不是anlice

2.比較表達式

== 等于 
!= 不等于                      
< 小于 
> 大于
<= 小于 
>= 大于等于

== 等于 != 不等于 兩邊可以是數(shù)字也可以是字符串

[root@localhost tmp]# awk -F: '$NF == "alice" ' /etc/passwd      #最后一個字段是anlice (別忘了字符串要引起來)
[root@localhost tmp]# awk -F: '$3== 0' /etc/passwd      #第三個字段是0
[root@localhost tmp]# awk -F: '$3 > 0 ' /etc/passwd      #第三個字段大于0

3.條件表達式:if if else
4.邏輯表達式:
&& 與 同時滿足
|| 或 滿足其中一個
! 非 取反
5.范圍模式
起始表達式, 終止表達式

[root@localhost tmp]# awk -F: '/^bin/,/adm/ {print $0 }' /etc/passwd
#從開頭是 bin 的行開始匹配成功一直到含有 adm 的行結(jié)束匹配(中間的行也都打印出來)

6.外部變量的引用
一般是用awk -v 參數(shù)

[root@localhost tmp]# test=hello
[root@localhost tmp]# echo "hello world" | awk -v var=$test '$1 == var {print $1}'
hello

5.sed

sed的工作模式跟awk的一樣,都是一行一行的進行處理
sed也支持正則表達式,也支持擴展正則,但是要用-r參數(shù)來使用擴展正則。所以在實際使用中一般都加上-r參數(shù),即使你使用的不是擴展正則也不會報錯。
sed 默認會輸出文件的每一行,無論這行內(nèi)容是否能匹配上匹配模式,假如被匹配到的則會再輸出一次。屏蔽默認輸出使用 -n 參數(shù)
-i 參數(shù)是改變文件里面的內(nèi)容,不加這個參數(shù),只是輸出的時候改變,但是實際上文件里面沒有變化

1.實際中用的最多的----搜索替換
# 搜索每一行,找到有 root 的,把第一個替換為yjssjm
sed  -rn  's/root/yjssjm/'   filename
# 搜索每一行,找到所有的 root 字符,進行全局替換為 yjssjm
sed  -rn  's/root/yjssjm/g'   filename     
# i  是同時忽略大小寫
sed  -rn  's/root/yjssjm/gi'    filename #也就是可以將Root ROot 等替換成yjssjm
# 找到含有 root 的進行刪除
sed  -rn  '/root/d'   filename
# 可以使用不同的 字符 作為界定符號,注意進行轉(zhuǎn)義
sed  -rn  '\#root#d'  filename
# 第 1 行到第 3 行都刪除
sed  -r  '1,3  d'    filename
2.sed常用命令

1.替換命令:s

# 將所有的兩位數(shù)字后面加.5
[root@localhost tmp]# echo "77      1"|sed -r 's/[0-9][0-9]/&.5/'
77.5      1
#/()/\1/  注意格式
[root@localhost tmp]# echo "nowrite" | sed -r 's/(no)write/\1寫/'
no寫

2.追加命令:a (在匹配到的這一行后面追加)

[root@localhost tmp]# echo "aaaaaaa" | sed -r 'a\111111111'
aaaaaaa
111111111

3.插入命令:i (在匹配到的這一行前面插入)

[root@localhost tmp]# echo "aaaaaaa" | sed -r 'i\111111111'
111111111
aaaaaaa

4.修改命令:c

[root@localhost tmp]# echo "aaaaaaa" | sed -r 'c\111111111'
111111111
3.多重編輯選項:-e
sed -re '1,3 d' -re 's/root/yjssjm/' filename
等同于
sed -r '1,3 d; s/root/yjssjm/' filename
或者多行命令
sed -r '1,3 d' filename
sed -r 's/root/yjssjm/'dfilename
4.常見的操作

在文件中使用 :set list 就能看出來一些不顯示的特殊符號
比如:$在開頭表示空行,$在末尾表示回車

刪除配置文件中被注釋的行
sed -ri '/^#/d' filename
刪除配置文件中空行
sed -ri '/^$/d' filename
刪除開頭的一個或者多個空格或者Tab鍵
sed -ri '/^[ \t]*#/d' filename
給文件3到7行添加注釋
sed -r '3,7s/^/#/' filename

你們的評論和點贊是我寫文章的最大動力,蟹蟹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 搞懂Python 正則表達式用法 Python 正則表達式 正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一...
    廈熱閱讀 1,776評論 0 2
  • re模塊手冊 本模塊提供了和Perl里的正則表達式類似的功能,不關(guān)是正則表達式本身還是被搜索的字符串,都可以...
    喜歡吃栗子閱讀 4,198評論 0 13
  • 概念 正則表達式,又稱正規(guī)表示式、正規(guī)表示法、正規(guī)表達式、規(guī)則表達式、常規(guī)表示法(英語:Regular Expre...
    dxldeng閱讀 2,660評論 0 2
  • 正則表達式、re模塊、匹配單個字符、匹配多個字符、匹配開頭結(jié)尾、匹配分組、re模塊的高級用法、python貪婪和非...
    Cestine閱讀 1,767評論 0 1
  • 元字符 注意匹配時要匹配原始字符串,避免發(fā)生沖突 用 r” . ^ $ * + ? {} [] () \ | .匹...
    鏡澤閱讀 1,506評論 0 1

友情鏈接更多精彩內(nèi)容