文本處理三劍客


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一樣,也是逐行讀取,是以字段為單位來處理文本


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM