欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Shell編程筆記之正則表達(dá)式與文本處理器詳解

 更新時(shí)間:2025年04月24日 10:39:11   作者:YUNYINGXIA  
這篇文章主要介紹了Shell編程筆記之正則表達(dá)式與文本處理器的相關(guān)資料,正則表達(dá)式用于精準(zhǔn)匹配字符串,而文本處理器如grep、sed、awk則用于高效處理文本,通過學(xué)習(xí)正則表達(dá)式的基礎(chǔ)和擴(kuò)展表達(dá)式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、引言

在 Shell 編程領(lǐng)域,正則表達(dá)式與文本處理器是極為關(guān)鍵的工具。正則表達(dá)式憑借其強(qiáng)大的字符串匹配能力,可精準(zhǔn)定位符合特定規(guī)則的字符串;而 grep、sed、awk 等文本處理器,能高效處理文本內(nèi)容,滿足各類文本處理需求。掌握這些知識(shí),對(duì)編寫高效、靈活的 Shell 腳本意義重大,本筆記將深入學(xué)習(xí)相關(guān)內(nèi)容。

二、正則表達(dá)式

2.1 定義與用途

正則表達(dá)式(Regular Expression,簡(jiǎn)稱 RE),又稱正規(guī)表達(dá)式、常規(guī)表達(dá)式,在代碼中常簡(jiǎn)寫為 regex、regexp 或 RE。它是用單個(gè)字符串描述、匹配一系列符合特定句法規(guī)則字符串的方法,在腳本編程、文本編輯器及多種編程語言中都占據(jù)核心地位。在 Shell 編程里,可利用正則表達(dá)式進(jìn)行文本的查找、刪除、替換等操作,提升文本處理效率。

2.2 基礎(chǔ)正則表達(dá)式

學(xué)習(xí)基礎(chǔ)正則表達(dá)式,需借助測(cè)試文件 test.txt,其內(nèi)容如下:

he was short and fat. He was wearing a blue polo shirt with black pants.The home
of Football on BBC Sport online.
the tongue is boneless but it breaks bones.12!
google is the best tools for search keyword. The year ahead will test our political
establishment to the limit. P1=3.141592653589793238462643383249901429
a wood cross!
Actions speak louder than words
#woood #
#woooooood #
Axy zxyzxyzxyzC
I bet this place is really spooky late at night!
Misfortunes never come alone/single.
I shouldn't have lett so tast.

2.2.1 查找特定字符

使用 grep 命令查找特定字符。-n選項(xiàng)用于顯示行號(hào),-i選項(xiàng)表示不區(qū)分大小寫,-v選項(xiàng)實(shí)現(xiàn)反向選擇(查找不包含指定字符的行)。

  • 查找 “the” 所在位置:
[root@localhost ~]# grep -n 'the' test.txt
4:the tongue is boneless but it breaks bones.12!
5:google is the best tools for search keyword. 
6:The year ahead will test our political establishment to the limit.
  • 不區(qū)分大小寫查找 “the”:
[root@localhost ~]# grep -in 'the' test.txt
3:The home of Football on BBC Sport online. 
4:the tongue is boneless but it breaks bones.12!
5:google is the best tools for search keyword. 
6:The year ahead will test our political establishment to the limit.
  • 查找不包含 “the” 的行:
[root@localhost ~]# grep -vn 'the' test.txt
1:he was short and fat. 
2:He was wearing a blue polo shirt with black pants. 
3:The home of Football on BBC Sport online. 
7:p13.141592653589793238462643383249901429
8:a wood cross!
9:Actions speak louder than words
10:
11:#woood #
12:#wo0000ood #
13:AxyzxyzxyzxyzC
14:I bet this place is really spooky late at night!
15:Misfortunes never come alone/single. 
16:I shouldn't have lett so tast.

2.2.2 利用中括號(hào) “[]” 查找集合字符

“[]” 內(nèi)的多個(gè)字符僅代表一個(gè)字符。

  • 查找 “shirt” 與 “short”:
[root@localhost ~]# grep -n 'sh[io]rt' test.txt
1:he was short and fat. 
2:He was wearing a blue polo shirt with black pants.
  • 查找包含重復(fù)單個(gè)字符 “oo” 的字符串:
[root@localhost ~]# grep -n 'oo' test.txt
3:The home of Football on BBC Sport online. 
5:google is the best tools for search keyword. 
8:a wood cross!
11:#woood #
12:#woo00oood #
14:I bet this place is really spooky late at night!
  • 查找 “oo” 前面不是 “w” 的字符串:
[root@localhost ~]# grep -n '[^w]oo' test.txt
3:The home of Football on BBC Sport online. 
5:google is the best tools for search keyword. 
11:#woood #
12:#wooo0oood #
14:I bet this place is really spoky late at night!
  • 查找不希望 “oo” 前面存在小寫字母的字符串:
[root@localhost ~]# grep -n '[^a-z]oo' test.txt
3:The home of Football on BBC Sport online.
  • 查找包含數(shù)字的行:
[root@localhost ~]# grep -n '[0-9]' test.txt
4:the tongue is boneless but it breaks bones.12!
7:PI=3.141592653589793238462643383249901429

2.2.3 查找行首 “^” 與行尾字符 “$”

“^” 表示行首,“$” 表示行尾。

  • 查找以 “the” 為行首的行:
[root@localhost ~]# grep -n '^the' test.txt
4:the tongue is boneless but it breaks bones.12!
  • 查找以小寫字母開頭的行:
[root@localhost ~]# grep -n '^[a-z]' test.txt
1:he was short and fat. 
4:the tongue is boneless but it breaks bones.12!
5:google is the best tools for search keyword. 
8:a wood cross!
  • 查找以大寫字母開頭的行:
[root@localhost ~]# grep -n '^[A-Z]' test.txt
2:He was wearing a blue polo shirt with black pants. 
3:The home of Football on BBC Sport online. 
6:The year ahead will test our political establishment to the limit.
7:PI=3.141592653589793238462643383249901429
9:Actions speak louder than words
13:AxyzxyzxyzxyzC
14:I bet this place is really spooky late at night!
15:Misfortunes never come alone/single. 
16:I shouldn't have lett so tast.
  • 查找不以字母開頭的行:
[root@localhost ~]# grep -n '^[^a-zA-Z]' test.txt
11:#woood #
12:#woo000ood #
  • 查找以小數(shù)點(diǎn) “.” 結(jié)尾的行(“.” 是元字符,需用 “\” 轉(zhuǎn)義):
[root@localhost ~]# grep -n '\.$' test.txt
1:he was short and fat. 
2:He was wearing a blue polo shirt with black pants. 
3:The home of Football on BBC Sport online. 
5:google is the best tools for search keyword.
6:The year ahead will test our political establishment to the limit. 
15:Misfortunes never come alone/single. 
16:I shouldn't have lett so tast.
  • 查找空白行:
[root@localhost ~]# grep -n '^$' test.txt
10:

2.2.4 查找任意一個(gè)字符 “.” 與重復(fù)字符 “*”

“.” 代表任意一個(gè)字符,“*” 代表重復(fù)零個(gè)或多個(gè)前面的單字符。

  • 查找 “w??d” 的字符串:
[root@localhost ~]# grep -n 'w..d' test.txt
5:google is the best tools for search keyword.
8:a wood cross!
9:Actions speak louder than words
  • 查找包含至少兩個(gè) “o” 以上的字符串:
[root@localhost ~]# grep -n 'ooo*' test.txt
3:The home of Football on BBC Sport online. 
5:google is the best tools for search keyword. 
8:a wood cross!
11:#woood #
12:#woo00oood #
14:I bet this place is really spooky late at night!
  • 查找以 “w” 開頭 “d” 結(jié)尾,中間包含至少一個(gè) “o” 的字符串:
[root@localhost ~]# grep -n 'woo*d' test.txt
8:a wood cross!
11:#woood #
12:#woooooood #
  • 查找以 “w” 開頭 “d” 結(jié)尾,中間字符可有可無的字符串:
[root@localhost ~]# grep -n 'w.*d' test.txt
1:he was short and fat. 
5:google is the best tools for search keyword. 
8:a wood cross!
9:Actions speak louder than words
11:#woood #
12:#woo00oood #
  • 查找任意數(shù)字所在行:
[root@localhost ~]# grep -n '[0-9][0-9]*' test.txt
4:the tongue is boneless but it breaks bones.12!
7:PI=3.141592653589793238462643383249901429

2.2.5 查找連續(xù)字符范圍 “{}”

“{}” 用于限制重復(fù)字符串的范圍,在 Shell 中使用需轉(zhuǎn)義。

  • 查找兩個(gè) “o” 的字符:
[root@localhost ~]# grep -n 'o\{2\}' test.txt
3:The home of Football on BBC Sport online. 
5:google is the best tools for search keyword. 
8:a wood cross!
11:#woood #
12:#wo0000ood #
14:I bet this place is really spooky late at night!
  • 查找以 “w” 開頭以 “d” 結(jié)尾,中間包含 2 - 5 個(gè) “o” 的字符串:
[root@localhost ~]# grep -n 'wo\{2,5\}d' test.txt
8:a wood cross!
11:#woood #
  • 查找以 “w” 開頭以 “d” 結(jié)尾,中間包含 2 個(gè)或 2 個(gè)以上 “o” 的字符串:
[root@localhost ~]# grep -n 'wo\{2,\}d' test.txt
8:a wood cross!
11:#woood #
12:#woo00oood #

2.3 元字符總結(jié)

字符

描述

\

將下一個(gè)字符標(biāo)記為一個(gè)特殊字符、或一個(gè)原義字符、或一個(gè) 向后引用、或一個(gè)八進(jìn)制轉(zhuǎn)義符。例如,'n' 匹配字符 "n"。'\n' 匹配一個(gè)換行符。序列 '\\' 匹配 "\" 而 "\(" 則匹配 "("。

^

匹配輸入字符串的開始位置。如果設(shè)置了 RegExp 對(duì)象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之后的位置。

$

匹配輸入字符串的結(jié)束位置。如果設(shè)置了RegExp 對(duì)象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。

*

匹配前面的子表達(dá)式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價(jià)于{0,}。

+

匹配前面的子表達(dá)式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價(jià)于 {1,}。

?

匹配前面的子表達(dá)式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。? 等價(jià)于 {0,1}。

{n}

n 是一個(gè)非負(fù)整數(shù)。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個(gè) o。

{n,}

n 是一個(gè)非負(fù)整數(shù)。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等價(jià)于 'o+'。'o{0,}' 則等價(jià)于 'o*'。

{n,m}

m 和 n 均為非負(fù)整數(shù),其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 將匹配 "fooooood" 中的前三個(gè) o。'o{0,1}' 等價(jià)于 'o?'。請(qǐng)注意在逗號(hào)和兩個(gè)數(shù)之間不能有空格。

?

當(dāng)該字符緊跟在任何一個(gè)其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時(shí),匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認(rèn)的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對(duì)于字符串 "oooo",'o+?' 將匹配單個(gè) "o",而 'o+' 將匹配所有 'o'。

.

匹配除換行符(\n、\r)之外的任何單個(gè)字符。要匹配包括 '\n' 在內(nèi)的任何字符,請(qǐng)使用像"(.|\n)"的模式。

(pattern)

匹配 pattern 并獲取這一匹配。所獲取的匹配可以從產(chǎn)生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中則使用 $0…$9 屬性。要匹配圓括號(hào)字符,請(qǐng)使用 '\(' 或 '\)'。

(?:pattern)

匹配 pattern 但不獲取匹配結(jié)果,也就是說這是一個(gè)非獲取匹配,不進(jìn)行存儲(chǔ)供以后使用。這在使用 "或" 字符 (|) 來組合一個(gè)模式的各個(gè)部分是很有用。例如, 'industr(?:y|ies) 就是一個(gè)比 'industry|industries' 更簡(jiǎn)略的表達(dá)式。

(?=pattern)

正向肯定預(yù)查(look ahead positive assert),在任何匹配pattern的字符串開始處匹配查找字符串。這是一個(gè)非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。預(yù)查不消耗字符,也就是說,在一個(gè)匹配發(fā)生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預(yù)查的字符之后開始。

(?!pattern)

正向否定預(yù)查(negative assert),在任何不匹配pattern的字符串開始處匹配查找字符串。這是一個(gè)非獲取匹配,也就是說,該匹配不需要獲取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。預(yù)查不消耗字符,也就是說,在一個(gè)匹配發(fā)生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預(yù)查的字符之后開始。

(?<=pattern)

反向(look behind)肯定預(yù)查,與正向肯定預(yù)查類似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。

(?<!pattern)

反向否定預(yù)查,與正向否定預(yù)查類似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。

x|y

匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。

[xyz]

字符集合。匹配所包含的任意一個(gè)字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。

[^xyz]

負(fù)值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n'。

[a-z]

字符范圍。匹配指定范圍內(nèi)的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范圍內(nèi)的任意小寫字母字符。

[^a-z]

負(fù)值字符范圍。匹配任何不在指定范圍內(nèi)的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范圍內(nèi)的任意字符。

\b

匹配一個(gè)單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

\B

匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

\cx

匹配由 x 指明的控制字符。例如, \cM 匹配一個(gè) Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個(gè)原義的 'c' 字符。

\d

匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9]。

\D

匹配一個(gè)非數(shù)字字符。等價(jià)于 [^0-9]。

\f

匹配一個(gè)換頁符。等價(jià)于 \x0c 和 \cL。

\n

匹配一個(gè)換行符。等價(jià)于 \x0a 和 \cJ。

\r

匹配一個(gè)回車符。等價(jià)于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、換頁符等等。等價(jià)于 [ \f\n\r\t\v]。

\S

匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v]。

\t

匹配一個(gè)制表符。等價(jià)于 \x09 和 \cI。

\v

匹配一個(gè)垂直制表符。等價(jià)于 \x0b 和 \cK。

\w

匹配字母、數(shù)字、下劃線。等價(jià)于'[A-Za-z0-9_]'。

\W

匹配非字母、數(shù)字、下劃線。等價(jià)于 '[^A-Za-z0-9_]'。

2.4 擴(kuò)展正則表達(dá)式

擴(kuò)展正則表達(dá)式可簡(jiǎn)化指令,grep 命令僅支持基礎(chǔ)正則表達(dá)式,使用擴(kuò)展正則表達(dá)式需用 egrep 或 awk 命令。egrep 命令與 grep 用法相似,可搜索文件中的任意字符串和符號(hào)。

元字符含義示例及解釋
+匹配前面的子表達(dá)式一次或多次,即至少出現(xiàn)一次。模式 go+gle 能匹配 google、gooogle 等,但無法匹配 gle
?匹配前面的子表達(dá)式零次或一次,也就是該字符可有可無。模式 colou?r 能匹配 color 和 colour。
|表示或關(guān)系,用于匹配多個(gè)選擇中的任意一個(gè)。模式 cat|dog 可以匹配 cat 或者 dog。
()用于分組,將多個(gè)字符組合成一個(gè)整體,便于后續(xù)操作,還可用于后向引用。模式 (ab)+ 能匹配 ab、abab 等;(\d{3})-(\d{4}) 可將電話號(hào)碼分為區(qū)號(hào)和號(hào)碼兩部分,方便后續(xù)引用。
{m,n}指定前面的子表達(dá)式出現(xiàn)的次數(shù)范圍,m 是下限,n 是上限,都為非負(fù)整數(shù)且 m <= n。若省略 m,則表示 0 到 n 次;若省略 n,則表示至少 m 次。模式 a{2,4} 能匹配 aa、aaa、aaaa;a{3,} 能匹配 aaa、aaaa 等。

例如,查詢除文件中空白行與行首為 “#” 之外的行,基礎(chǔ)正則表達(dá)式需用管道命令搜索兩次:

[root@localhost ~]# grep -v '^$' test.txt|grep -v '^#'

擴(kuò)展正則表達(dá)式可簡(jiǎn)化為:

[root@localhost ~]# egrep -v '^$|^#' test.txt

三、文本處理器

3.1 sed 工具

sed(Stream EDitor)是強(qiáng)大且簡(jiǎn)單的文本解析轉(zhuǎn)換工具,可讀取文本并編輯,廣泛應(yīng)用于 Shell 腳本。

3.1.1 工作流程

sed 工作流程包括讀取、執(zhí)行和顯示三個(gè)過程:

  • 讀取:從輸入流(文件、管道、標(biāo)準(zhǔn)輸入)讀取一行內(nèi)容到臨時(shí)緩沖區(qū)(模式空間)。
  • 執(zhí)行:默認(rèn)在模式空間順序執(zhí)行 sed 命令,除非指定行地址,否則在所有行依次執(zhí)行。
  • 顯示:將修改后的內(nèi)容發(fā)送到輸出流,發(fā)送后清空模式空間。該過程重復(fù)直至所有內(nèi)容處理完。默認(rèn)情況下,輸入文件不會(huì)改變,除非用重定向存儲(chǔ)輸出。

3.1.2 命令選項(xiàng)

常見 sed 命令選項(xiàng):

選項(xiàng)完整形式說明
-e--expression=用指定命令或腳本來處理輸入文本文件
-f--file=用指定的腳本文件來處理輸入文本文件
-h--help顯示幫助
-n--quiet、silent僅顯示處理后的結(jié)果
-i直接編輯文本文件

3.1.3 操作命令

“操作” 指定對(duì)文件的動(dòng)作行為,格式通常為 “[n1 [,n2]] 操作參數(shù)”,n1、n2 可選,代表操作的行數(shù)。常見操作:

操作說明
a在當(dāng)前行下面增加一行指定內(nèi)容
c將選定行替換為指定內(nèi)容
d刪除選定的行
i在選定行上面插入一行指定內(nèi)容
p指定行則打印指定行,不指定則打印所有內(nèi)容,有非打印字符以 ASCII 碼輸出,常與 “-n” 選項(xiàng)一起使用
s替換指定字符
y字符轉(zhuǎn)換

3.1.4 用法示例

以 test.txt 文件為例:

輸出符合條件的文本

輸出所有內(nèi)容:

[root@localhost ~]# sed -n 'p' test.txt

輸出第 3 行:

[root@localhost ~]# sed -n '3p' test.txt

輸出 3 - 5 行:

[root@localhost ~]# sed -n '3,5p' test.txt

輸出所有奇數(shù)行:

[root@localhost ~]# sed -n 'p;n' test.txt

輸出所有偶數(shù)行:

[root@localhost ~]# sed -n 'n;p' test.txt

輸出第 1 - 5 行之間的奇數(shù)行:

[root@localhost ~]# sed -n '1,5{p;n}' test.txt

輸出第 10 行至文件尾之間的偶數(shù)行:

[root@localhost ~]# sed -n '10,${n;p}' test.txt

輸出包含 “the” 的行:

[root@localhost ~]# sed -n '/the/p' test.txt

輸出從第 4 行至第一個(gè)包含 “the” 的行:

[root@localhost ~]# sed -n '4,/the/p

 3.2 awk 工具

3.2.1 awk 工具概述與命令格式

awk 是功能強(qiáng)大的編輯工具,逐行讀取文本,根據(jù)匹配模式查找、格式化輸出或過濾處理。命令格式為:

awk選項(xiàng)'模式或條件{編輯指令}'文件1文件2...
awk -f腳本文件文件1文件2...

awk 傾向于將一行分成多個(gè) “字段” 處理,默認(rèn)字段分隔符為空格或 tab 鍵,可使用邏輯操作符和進(jìn)行數(shù)學(xué)運(yùn)算。

3.2.2 awk 內(nèi)建變量

FS指定每行文本的字段分隔符,默認(rèn)為空格或制表位
NF當(dāng)前處理的行的字段個(gè)數(shù)
NR當(dāng)前處理的行的行號(hào)(序數(shù))
$0當(dāng)前處理的行的整行內(nèi)容
$n當(dāng)前處理行的第 n 個(gè)字段(第 n 列)
FILENAME被處理的文件名
RS數(shù)據(jù)記錄分隔,默認(rèn)為\n,即每行為一條記錄

3.2.3 awk 用法示例

按行輸出文本:輸出所有內(nèi)容:

awk '{print}' test.txt
awk '{print $0}' test.txt

輸出第 1 - 3 行內(nèi)容:

awk 'NR==1, NR==3{print}' test.txt
awk '(NR>=1)&&(NR<=3){print}' test.txt

總結(jié) 

到此這篇關(guān)于Shell編程筆記之正則表達(dá)式與文本處理器的文章就介紹到這了,更多相關(guān)Shell正則表達(dá)式與文本處理器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論