1、簡介
awk、grep、sed是linux操作文本的三大利器,合稱文本三劍客。三者的功能都是處理文本,但側重點各不相同,其中屬awk功能最強大,但也最復雜。grep更適合單純地查找或匹配文本;sed更適合編輯匹配到的文本,awk更適合格式化文本,對文本進行較復雜格式處理。
2、grep
2.1、什么是grep和egrep
Linux系統中grep命令是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並將匹配的行打印出來(匹配到的標紅)。grep全稱是Global Regular Expression Print,表示全局正則表達式版本,它的使用權限是所有用戶。
grep的工作方式是這樣的,它在一個或多個文件中搜索字符串模板。如果模板包括空格,則必須被引用,模板后的所有字符串被看做是文件名。搜索的結果被送到標准輸出,不影響原文件內容。
grep可用於shell腳本,因為grep通過一個返回狀態值來說明搜索的狀態,如果模板搜索成功,則返回0;如果搜索不成功,則返回1;如果搜索的文件不存在,則返回2。可利用這些返回值進行一些自動化的文本處理工作。
egrep等同於grep -E:擴展的正則表達式(除了\<,\>,\b之外,使用其他正則都可以去掉\)
2.2、使用grep
2.2.1、命令格式
grep [option] pattern file
2.2.2、命令功能
用於過濾/搜索特定字符。可配合正則表達式來進行使用,使用上十分靈活。
2.2.3、命令參數
常用參數已加粗。
- -A<顯示行數>:除了顯示符合樣式的那一行之外,並顯示該行之后的內容。
- -B<顯示行數>:除了顯示符合樣式的那一行之外,並顯示該行之前的內容。
- -C<顯示行數>:除了顯示符合樣式的那一行之外,並顯示該行之前后的內容。
- -c:統計匹配的行數
- -e:實現多個選項間的邏輯or關系
- -E:擴展的正則表達式
- -f file:從file獲取pattern匹配
- -F:相當於fgrep
- -i --ignore-case:忽略字符大小寫的差別
- -n:顯示匹配的行號
- -o:僅顯示匹配到的字符串
- -q:靜默模式,不輸出任何信息
- -s:不顯示錯誤信息
- -v:顯示不被pattern匹配到的行,相當於[^]反向匹配
- -w:匹配整個單詞
2.2.4、實戰演示

#
[root@docker test]# cat grep.txt
aaa
[root@docker test]# cat test
aaa
bbbbb
AAAaaa
BBBBASDABBDA
#以grep.txt中每一行為關鍵字,查找test文件中匹配的行
[root@docker test]# grep -f grep.txt test
aaa
AAAaaa
3、正則表達式
3.1 分類
POSIX規范將正則表達式分為了兩種
- 基本正則表達式(BRE,basic regular expression)
- 高級功能:擴展正則表達式(ERE,extended regular expression)
BRE和ERE的區別僅僅是元字符的不同
- BRE只承認的元字符有^$.[]*,其他字符識別為普通字符;
- ERE則添加了(){}?+|等
- 只用在用反斜杠“\”進行轉義的情況下,字符串(){}才會在BRE被當做元字符處理,而在BRE中,任何元字符前面加上反斜杠反而會使其被當做普通字符來處理。
3.2、基本正則表達式
3.2.1、格式
| 字符 | 描述 |
|---|---|
| ^ | ^word:搜索以word開頭的內容 |
| $ | word$:搜索以word結尾的內容 |
| ^$ | 表示空行,不是空格 |
| . | 代表且只能代表任意一個字符(不匹配空行) |
| \ | 轉義字符,讓有特殊含義的字符脫掉馬甲,現出原形,如\.只表示小數點 |
| * | 匹配前面的字符任意次,包括0次,貪婪模式:盡可能長的匹配 |
| .* | 任意長度的任意字符,不包括0次 |
| ^.* | 以任意多個字符串開頭,.*盡可能多,有多少算多少,貪婪性 |
| [^abc] | 匹配不包含^后的任意字符a或b或c,是對[abc]的取反 |
| a\ | 重復前面a字符至少n次,至多m次(如使用egrep或sed -r可去掉斜線) |
3.2.2、演練





3.3、擴展正則表達式
3.3.1、格式
| 特殊字符 | 描述 |
|---|---|
| + | 重復前一個字符一次或多次 |
| ? | 重復前一個字符0次或1次(.是有且只有1個) |
| | | 表示或,查找多個字符串 |
| () | 分組過濾被括起來的東西表示一個整體(一個字符) |
3.3.2、演練




3.4、基本正則和擴展正則區別
所謂基礎正則,實際上就是得需要轉義字符配合表達的正則,而擴展正則就是讓命令擴展它的權限讓其直接就認識正則表達符號
| BRE | ERE |
|---|---|
| ? | ? |
| \+ | + |
| \ | {} |
| \(\) | () |
| \ |
3.5、補充說明
3.5.1、預定義
| 正則表達式 | 描述 | 示例 |
|---|---|---|
| [:alnum:] | [a-zA-Z0-9]匹配任意一個字母或數字字符 | [[:alnum:]]+ |
| [:alpha:] | 匹配任意一個字母字符(包括大小寫字母) | [[:alpha:]] |
| [:blank:] | 空格與制表符(橫向縱向) | [[:blank:]]* |
| [:digit:] | 匹配任意一個數字字符 | [[:digit:]]? |
| [:lower:] | 匹配小寫字母 | [[:lower:]] |
| [:upper:] | 匹配大寫字母 | ([[:upper:]]+)? |
| [:punct:] | 匹配標點符號 | [[:punct:]] |
| [:space:] | 匹配一個包括換行符,回車等在內的所有空白符 | [[:space:]]+ |
| [:graph:] | 匹配任何一個可以看得見的且可以打印的字符 | [[:graph:]] |
| [:xdigit:] | 任何一個十六進制數 | [[:xdigit:]]+ |
| [:cntrl:] | 任何一個控制字符(ASCII字符集中的前32個字符) | [[:cntrl:]] |
| [:print:] | 任何一個可以打印的字符 | [[:print:]] |
3.5.2、元字符
元字符是一種Perl風格的正則表達式,只有一部分文本處理工具支持它,並不是所有的文本處理工具都支持。
| 正則表達式 | 描述 | 示例 |
|---|---|---|
| \b | 單詞邊界 | \bcool\b匹配cool,不匹配coolant |
| \B | 非單詞邊界 | cool\B匹配coolant不匹配cool |
| \d | 單個數字字符 | b\db匹配b2b,不匹配bcb |
| \D | 單個非數字字符 | b\Db匹配bcb不匹配b2b |
| \w | 單個單詞字符(字母,數字與_) | \w匹配1或a,不匹配& |
| \W | 單個非單詞字符 | \W匹配&,不匹配1或a |
| \n | 換行符 | \n匹配一個新行 |
| \s | 單個空白字符 | x\sx匹配xx,不匹配xx |
| \S | 單個非空白字符 | x\S\x匹配xkx,不匹配xx |
| \r | 回車 | \r匹配回車 |
| \t | 橫向制表符 | \t匹配一個橫向制表符 |
| \v | 垂直制表符 | \v匹配一個垂直制表符 |
| \f | 換頁符 | \f匹配一個換頁符 |
4、sed
4.1、認識sed
sed是一種流編輯器,它一次處理一行內容。處理時,把當前處理的行存儲在臨時緩沖區中,稱為“模式空間”,接着用sed命令處理緩沖區中的內容,處理完成后,把緩沖區的內容送往屏幕。然后讀入下一行,執行下一個循環。如果沒有使用諸如“D”的特殊命令,那會在兩個循環之間清空模式空間,但不會清空保留空間。這樣不斷重復,直到文件末尾。文件內容並沒有改變,除非使用重定向存儲輸出或-i。
功能:主要用來自動編輯一個或多個文件,簡化對文件的反復操作。
4.2、使用sed
4.2.1、命令格式
sed [選項] [command] 文件名
4.2.2、常用選項
- -n:不輸出模式空間內容到屏幕,即不自動打印,只打印匹配到的行
- -e:多點編輯,對每行處理時,可以有多個script
- -f:把script寫到文檔中,在執行sed時,-f指定文件路徑;如果有多個script,換行寫入
- -r:支持擴展的正則表達式
- -i:直接將處理的結果寫入文件
- -i.bak:在將處理的結果寫入文件之前備份一份
4.2.3、地址定界
- 不給地址:對全文進行處理
- 單地址:
- #: 指定的行
- /pattern/:被此處模式所能夠匹配到的每一行
- 地址范圍:
- #,#
- #,+#
- /pat1/,/pat2/
- #,/pat1/
- ~:步進
- sed -n '1~2p' 只打印奇數行 (1~2 從第1行,一次加2行)
- sed -n '2~2p' 只打印偶數行
4.2.4、編輯命令
- d:刪除模式空間匹配的行,並立即啟用下一輪循環
- p:打印當前模式空間內容,追加到默認輸出之后
- a:在指定行后面追加文本,支持使用\n實現多行追加
- i:在行前面插入文本,支持使用\n實現多行追加
- c:替換行為單行或多行文本,支持使用\n實現多行追加
- w:保存模式匹配的行至指定文件
- r:讀取指定文件的文本至模式空間中匹配到的行后
- =:為模式空間中的行打印行號
- !:模式空間中匹配行取反處理
- s///:查找替換,支持使用其它分隔符,如:s@@@,s###;
- 加g表示行內全局替換;
- 在替換時,可以加一下命令,實現大小寫轉換
- \l:把下個字符轉換成小寫。
- \L:把replacement字母轉換成小寫,直到\U或\E出現。
- \u:把下個字符轉換成大寫。
- \U:把replacement字母轉換成大寫,直到\L或\E出現。
- \E:停止以\L或\U開始的大小寫轉換
4.3、演練
4.3.1、常用選項options
[root@aliyun shell]# cat demo
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed "/aaa/p" demo #匹配到的行會打印一遍,不匹配的行也會打印
aaa
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed -n "/aaa/p" demo #僅打印匹配的行,-n,不顯示沒匹配的行
aaa
[root@aliyun shell]# sed -e "s/a/A/" -e "s/b/B" demo
sed:-e 表達式 #2,字符 5:未終止的“s”命令
[root@aliyun shell]# sed -e "s/a/A/" -e "s/b/B/" demo #-e多點編輯
Aaa
Bbbb
AABBCCDD
[root@aliyun shell]# cat sedscript.sed
s/a/A/g
[root@aliyun shell]# sed -f sedscript.sed demo #-f 使用文件處理
AAA
bbbb
AABBCCDD
[root@aliyun shell]# sed -i.bak "s/a/A/g" demo #-i.bak直接對文本進行處理,同時將原文本備份為.bak文件
[root@aliyun shell]# cat demo
AAA
bbbb
AABBCCDD
[root@aliyun shell]# cat demo.bak
aaa
bbbb
AABBCCDD
4.3.2、地址界定
[root@aliyun shell]# cat demo
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed -n "p" demo #不指定行,打印全部內容
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed "2s/b/B/g" demo #替換第2行的b為B
aaa
BBBB
AABBCCDD
[root@aliyun shell]# sed -n "/aaa/p" demo
aaa
[root@aliyun shell]# sed -n "1,2p" demo #打印1-2行
aaa
bbbb
[root@aliyun shell]# sed -n "/aaa/,/DD/p" demo #打印aaa-DD行
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed -n "2,/DD/p" demo #打印2-DD行
bbbb
AABBCCDD
[root@aliyun shell]# sed "1~2s/[aA]/E/g" demo #將奇數行的a或A替換為E
EEE
bbbb
EEBBCCDD
4.3.3、編輯命令command
[root@aliyun shell]# cat demo
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed "2d" demo #刪除第2行
aaa
AABBCCDD
[root@aliyun shell]# sed -n "2p" demo #打印第二行
bbbb
[root@aliyun shell]# sed "2a123" demo #將123添加到第二行后面
aaa
bbbb
123
AABBCCDD
[root@aliyun shell]# sed "1i123" demo #將123添加到第一行前面
123
aaa
bbbb
AABBCCDD
[root@aliyun shell]# sed "3c123\n456" demo #將123\n456替換第三行
aaa
bbbb
123
456
[root@aliyun shell]# sed -n "3w/home/shell/demo3" demo #將第三行寫到/home/shell/demo3文件中
[root@aliyun shell]# cat demo3
AABBCCDD
[root@aliyun shell]# sed "1r/home/shell/demo3" demo #將/home/shell/demo3文件中內容讀取到第一行后面
aaa
AABBCCDD
bbbb
AABBCCDD
[root@aliyun shell]# sed -n "=" demo #打印行號
1
2
3
[root@aliyun shell]# sed "s@[a-z]@\u&@g" demo #將所有小寫字母轉換為大寫
AAA
BBBB
AABBCCDD
[root@aliyun shell]# sed -n '2!p' demo #除第二行內容外,全部打印
aaa
AABBCCDD
4.4、sed高級編輯命令
4.4.1、格式
- h:將模式空間中的內容覆蓋至保持空間中
- H:將模式空間中的內容追加至保持空間中
- g:從保持空間取出數據覆蓋至模式空間
- G:從保持空間取出數據追加至模式空間
- x:將模式空間中的內容與保持空間中的內容進行互換
- n:讀取匹配到的行的下一行覆蓋至模式空間
- N:讀取匹配到的行的下一行追加至模式空間
- d:刪除模式空間中的行
- D:刪除當前模式空間開端到\n的內容(不再傳至標准輸出),放棄之后的命令,但是對剩余模式空間重新執行sed
4.4.2、案例+示意圖
#倒敘輸出文件內容
[root@aliyun shell]# cat num.txt
1
2
3
[root@aliyun shell]# sed '1!G;h;$!d' num.txt
3
2
1
示意圖:

4.4.3、總結
保持空間是模式空間一個臨時存放數據的緩沖區,協助模式空間進行數據處理
4.4.4、演練
#顯示偶數行
[root@aliyun shell]# seq 9 | sed -n "n;p"
2
4
6
8
#倒敘顯示
[root@aliyun shell]# seq 9 | sed '1!G;h;$!d'
9
8
7
6
5
4
3
2
1
#顯示奇數行
[root@aliyun shell]# seq 9 | sed "H;n;d"
1
3
5
7
9
#打印最后一行
[root@aliyun shell]# seq 9 | sed "N;D"
9
#每行之間加空行
[root@aliyun shell]# seq 9 | sed "G"
1
2
3
4
5
6
7
8
9
#將每行內容替換成空行
[root@aliyun shell]# seq 9 | sed "g"
#確保每一行下面都有一個空行
[root@aliyun shell]# seq 9 | sed '/^$/d;G'
1
2
3
4
5
6
7
8
9
5、awk
5.1、簡介
awk是一種編程語言,用於在linux/unix下對文本和數據進行處理。數據可以來自於標准輸入、一個或多個文件、或其他命令的輸出。它支持用戶自定義函數和動態正則表達式等功能,是linux/unix下的一個強大的編程工具。它在命令行中使用,但更多是作為腳本使用。awk有很多內建的功能,比如數組、函數等。
5.2、使用awk
5.2.1、語法
[root@localhost ~]# awk [選項] '腳本命令' 文件名
5.2.2、常用命令選項
- -F fs:指定以fs作為輸入行的分隔符,awk命令默認分隔符為空格或制表符
- -v var=value:在執行處理過程之前,設置一個變量var,並給其設置初始值
- -f scriptfile:從腳本文件中讀取awk命令,以取代直接在命令行中輸入指令
awk的強大之處
awk的強大之處在於腳本命令,它由兩部分組成,分別為匹配規則和執行命令,如下所示:
'匹配規則{執行命令}'
這里的匹配規則,用來指定腳本命令中可以作用到文本內容中的具體行,可以使用字符串(比如/demo/,表示查看含有demo字符串的行)或正則表達式指定。
注:整個腳本命令是用單引號括起來,而其中的執行命令部分需要用大括號括起來
5.3、awk變量
5.3.1、內置變量
| 變量 | 描述 |
|---|---|
| FS | 輸入字符分隔符,默認為空白字符 |
| OFS | 輸出字段分隔符,默認為空白字符 |
| RS | 輸入記錄分隔符,指定輸入時的換行符,原換行符仍有效 |
| ORS | 輸出記錄分隔符,輸出時用指定符號代替換行符 |
| NF | 字符數量,共有多少個字段,$NF引用最后一列,$(NF-1)引用倒數第二列 |
| NR | 行號,后可跟多個文件,第二個文件行號則繼續從第一個文件最后行號開始 |
| FNR | 各文件分別計數,行號;后跟一個文件和NR一樣,跟多個文件,第二個文件行號從1開始 |
| FILENAME | 當前文件名 |
| ARGC | 命令行參數的個數 |
| ARGV | 數組,保存的是命令行所給定的各參數,查看參數 |
示例:
[root@aliyun shell]# cat awkdemo
hello:world
linux:redhat:lalala:hahaha
along:love:you
[root@aliyun shell]# awk -v FS=":" '{print $1,$2}' awkdemo #FS指定輸入分隔符
hello world
linux redhat
along love
[root@aliyun shell]# awk -v FS=":" -v OFS="---" '{print $1,$2}' awkdemo #OFS指定輸出分隔符
hello---world
linux---redhat
along---love
[root@aliyun shell]# awk -v RS=":" '{print $1,$2}' awkdemo
hello
world linux
redhat
lalala
hahaha along
love
you
[root@aliyun shell]# awk -v FS=":" -v ORS="---" '{print $1,$2}' awkdemo
hello world---linux redhat---along love---
[root@aliyun shell]# awk -F: '{print NF}' awkdemo
2
4
3
[root@aliyun shell]# awk -F: '{print $(NF-1)}' awkdemo
hello
lalala
love
[root@aliyun shell]# awk END'{print NR}' awkdemo
3
5.3.2、自定義變量
1、先定義變量,后執行動作
[root@aliyun shell]# cat awkdemo
hello:world
linux:redhat:lalala:hahaha
along:love:you
[root@aliyun shell]# awk -v name="along" -F: '{print name":"$0}' awkdemo
along:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you
2、先執行動作,后定義變量
[root@aliyun shell]# awk -F: '{print name":"$0;name="along"}' awkdemo
:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you
3、調用腳本進行定義
[root@aliyun shell]# cat awk.txt
{name="along";print name,$1}
[root@aliyun shell]# awk -F: -f awk.txt awkdemo
along hello
along linux
along along
[root@aliyun shell]#
6、grep、sed、awk對比
- grep主要用於搜索某些字符串;sed和awk用於處理文本。
- grep基本是以行為單位處理文本的
- sed是一個非交互性文本流編輯器,它編輯文件或標准輸入導出的文本拷貝。sed編輯器按照一次處理一行的方式來處理文件(或輸入)並將輸出送到屏幕上。sed把當前正在處理的行保存在一個臨時緩存里,這個緩存叫做模式空間;一旦sed完成了對模式空間里的行的處理,就把模式空間的行送到屏幕上(除非該命令要刪除該行或禁止打印);處理完該行之后,從模式空間中刪除它,然后把下一行讀入模式空間,進行處理並顯示。當輸入文件的最后一行處理完后,sed終止。通過將每一行存到一個臨時緩存里並編輯該行,初始文件不會被修改或被破壞。
- awk和sed一樣,也是逐行讀取,是以字段為單位來處理文本
