Linux?Shell編程之正則表達(dá)式與文本處理器用法詳解
前言
在 Linux 系統(tǒng)的 Shell 編程中,正則表達(dá)式與文本處理器是處理文本數(shù)據(jù)的核心工具,能夠?qū)崿F(xiàn)文本的快速查找、匹配、替換、過濾與格式化輸出。掌握這類工具的使用,能大幅提升 Shell 腳本的編寫效率,也是 Linux 運(yùn)維、開發(fā)人員的必備技能。本文將從基礎(chǔ)概念出發(fā),講解正則表達(dá)式的核心用法,并詳細(xì)介紹 Shell 編程中最常用的文本處理工具,同時(shí)補(bǔ)充實(shí)用知識點(diǎn),讓內(nèi)容更貼合實(shí)際應(yīng)用。
一、正則表達(dá)式基礎(chǔ)
1. 正則表達(dá)式的定義與作用
正則表達(dá)式(Regular Expression,簡稱 RE)是由普通字符(字母、數(shù)字、標(biāo)點(diǎn))和元字符(具有特殊含義的專用字符)組成的文本匹配模式,通過單個(gè)字符串描述一系列符合特定規(guī)則的字符串,實(shí)現(xiàn)對文本的高效檢索、替換和篩選。
在 Linux 系統(tǒng)中,正則表達(dá)式廣泛應(yīng)用于grep、sed、awk等文本工具,以及 Shell 腳本、日志分析、配置文件解析等場景,能快速從海量文本中提取關(guān)鍵信息,比如篩選日志中的錯(cuò)誤信息、匹配配置文件的指定參數(shù)等。
2. 正則表達(dá)式的分類
Linux 中常用的正則表達(dá)式分為兩類,適配不同的文本工具,核心區(qū)別在于元字符的支持范圍和使用方式:
- 基礎(chǔ)正則表達(dá)式(BRE):支持的元字符較少,語法更基礎(chǔ),
grep、sed等工具默認(rèn)支持。 - 擴(kuò)展正則表達(dá)式(ERE):在基礎(chǔ)正則的基礎(chǔ)上擴(kuò)展了更多元字符,簡化復(fù)雜匹配邏輯,
egrep、awk、grep -E等工具支持。
3. 基礎(chǔ)正則表達(dá)式核心元字符
基礎(chǔ)正則的元字符是文本匹配的基礎(chǔ),以下為核心元字符及用法,同時(shí)補(bǔ)充實(shí)用使用技巧:
表格
| 元字符 | 功能說明 | 實(shí)用示例 |
|---|---|---|
^ | 匹配行首,定位字符串在一行的開頭 | ^root 匹配以root開頭的行 |
| "" | 查找特定字符 | grep -n "the" test.txt(在test.txt文件中查找特定字符"the"所在位置并顯示行號) |
$ | 匹配行尾,定位字符串在一行的結(jié)尾 | nologin$ 匹配以nologin結(jié)尾的行 |
. | 匹配任意單個(gè)字符(不包含空行) | w..d 匹配以 w 開頭、d 結(jié)尾,中間含 2 個(gè)任意字符的字符串 |
* | 匹配前面的字符0 次或多次 | oo* 匹配 1 個(gè) o 及以上的連續(xù) o(o、oo、ooo...) |
[] | 匹配括號內(nèi)的任意單個(gè)字符,支持范圍 | [a-z]匹配小寫字母,[0-9]匹配數(shù)字,[sh]匹配 s 或 h |
[^] | 反向匹配,排除括號內(nèi)的字符 | [^0-9]匹配非數(shù)字字符 |
\ | 轉(zhuǎn)義符,將元字符還原為普通字符 | \. 匹配實(shí)際的小數(shù)點(diǎn),\*匹配實(shí)際的星號 |
\{n,m\} | 匹配前面字符n 到 m 次(BRE 需轉(zhuǎn)義,ERE 無需) | o\{2,3\} 匹配 2-3 個(gè)連續(xù)的 o |
示例1:查詢兩個(gè)o的字符
grep -n 'o\{2\}' test.txt
示例2:查詢以w開頭以d結(jié)尾,中間包含2~5個(gè)o的字符串
grep -n 'wo\{2,5\}d' test.txt
示例3:查詢以w開頭以d結(jié)尾,中間包含2個(gè)或2個(gè)以上o的字符串
grep -n 'wo\{2,\}d' test.txt補(bǔ)充知識點(diǎn):
- 空行匹配:
^$是正則中匹配空行的固定寫法,常用于過濾配置文件中的空行。 - 單詞邊界匹配:
\<和\>匹配單詞的開頭和結(jié)尾,如\<wood\>精準(zhǔn)匹配單詞wood,而非包含 wood 的字符串(如 woood)。
4. 元字符
表格
| 字符 | 說明 |
|---|---|
| \ | 將下一個(gè)字符標(biāo)記為一個(gè)特殊字符、或一個(gè)原義字符、或一個(gè)向后引用、或一個(gè)八進(jìn)制轉(zhuǎn)義符 |
| ^ | 匹配輸入字符串的開始位置 |
| $ | 匹配輸入字符串的結(jié)束位置 |
| * | 匹配前面的子表達(dá)式零次或多次 |
| + | 匹配前面的子表達(dá)式一次或多次 |
| ? | 匹配前面的子表達(dá)式零次或一次 |
| . | 匹配除換行符(\n、\r)之外的任何單個(gè)字符 |
| [a-z] | 字符范圍。匹配指定范圍內(nèi)的任意字符 |
| {n} | n 是一個(gè)非負(fù)整數(shù),匹配確定的 n 次 |
| {n,} | n 是一個(gè)非負(fù)整數(shù),至少匹配 n 次 |
| {n,m} | m 和 n 均為非負(fù)整數(shù),其中 n <= m。最少匹配 n 次且最多匹配 m 次 |
| \d | 匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9] |
| \D | 匹配一個(gè)非數(shù)字字符。等價(jià)于 [^0-9] |
| \s | 匹配任何空白字符,包括空格、制表符、換頁符等等。等價(jià)于 [\f\n\r\t\v] |
| \S | 匹配任何非空白字符。等價(jià)于 [^ \f\n\r\t\v] |
| \w | 匹配字母、數(shù)字、下劃線。等價(jià)于 [A-Za-z0-9_] |
| \W | 匹配非字母、數(shù)字、下劃線。等價(jià)于 [^A-Za-z0-9_] |
| \n | 匹配一個(gè)換行符 |
| \f | 匹配一個(gè)換頁符 |
| \r | 匹配一個(gè)回車符 |
補(bǔ)充知識點(diǎn):
- 擴(kuò)展正則的調(diào)用:
grep默認(rèn)不支持?jǐn)U展正則,需加-E選項(xiàng)(grep -E),效果等同于egrep。 - 多條件組合:擴(kuò)展正則可通過
()+|實(shí)現(xiàn)復(fù)雜多條件匹配,如(root|bin|daemon)匹配 root、bin、daemon 中的任意一個(gè)。
5.擴(kuò)展正則表達(dá)式
| 元字符 | 作用 | 示例 | |
|---|---|---|---|
| + | 作用:重復(fù)一個(gè)或者一個(gè)以上的前一個(gè)字符 | 示例:執(zhí)行 egrep -n 'wo+d' test.txt 命令,即可查詢 "wood" "wood" "wooooood" 等字符串 | |
| ? | 作用:零個(gè)或者一個(gè)的前一個(gè)字符 | 示例:執(zhí)行 egrep -n 'bes?t' test.txt 命令,即可查詢 "bet" "best" 這兩個(gè)字符串 | |
| | | 作用:使用或者(or)的方式找出多個(gè)字符 | 示例:執(zhí)行 `egrep -n 'of|is|on' test.txt`命令即可查詢"of"或者"if"或者"on" 字符串 | |
| () | 作用:查找 “組” 字符串 | 示例:`egrep -n 't (a|e) st' test.txt`。"tast"與"test"因?yàn)檫@兩個(gè)單詞的"t"與"st"是重復(fù)的,所以將"a"與"e"列于"()"符號當(dāng)中,并以""分隔,即可查詢"tast"或者"test" 字符串 | |
| ()+ | 作用:辨別多個(gè)重復(fù)的組 | 示例:egrep -n 'A(xyz)+C' test.txt。該命令是查詢開頭的 "A" 結(jié)尾是 "C",中間有一個(gè)以上的 "xyz" 字符串的意思 |
二、Shell 文本處理三劍客
Linux Shell 中,grep、sed、awk被稱為文本處理三劍客,各自聚焦不同的文本處理場景,搭配正則表達(dá)式使用能實(shí)現(xiàn)幾乎所有文本操作需求。三者的核心定位為:
grep:文本搜索工具,快速匹配并輸出符合條件的文本行,主打 “查找”。sed:流編輯器,按行處理文本,實(shí)現(xiàn)刪除、替換、添加、遷移等操作,主打 “編輯”。awk:文本分析器,按字段分割文本,實(shí)現(xiàn)數(shù)據(jù)提取、統(tǒng)計(jì)、格式化輸出,主打 “分析”。
1. 文本搜索:grep
核心功能
根據(jù)指定的正則表達(dá)式或字符串,在文件或輸入流中搜索匹配的文本行并輸出,支持基礎(chǔ) / 擴(kuò)展正則,是 Linux 中最常用的文本查找工具。
基本語法
grep [選項(xiàng)] '匹配模式' 目標(biāo)文件
常用選項(xiàng)(附補(bǔ)充知識點(diǎn))
表格
| 選項(xiàng) | 功能說明 |
|---|---|
-n | 顯示匹配行的行號 |
-i | 忽略大小寫匹配 |
-v | 反向匹配,輸出不滿足條件的行 |
-E | 支持?jǐn)U展正則表達(dá)式(等價(jià)于 egrep) |
-c | 僅統(tǒng)計(jì)匹配的行數(shù) |
-o | 僅輸出匹配的字符串,而非整行(補(bǔ)充) |
-r | 遞歸搜索目錄下的所有文件(補(bǔ)充) |
經(jīng)典示例
# 基礎(chǔ)匹配:查找test.txt中包含the的行,顯示行號 grep -n 'the' test.txt # 忽略大小寫:查找包含the的行,不區(qū)分大小寫 grep -ni 'the' test.txt # 反向匹配:過濾test.txt中的空行和以#開頭的注釋行(配置文件常用) grep -v '^$' test.txt | grep -v '^#' # 擴(kuò)展正則:查找包含cat或dog的行 grep -E 'cat|dog' test.txt # 遞歸搜索:查找/ect目錄下所有包含root的配置文件 grep -rn 'root' /etc/
2. 流編輯:sed
核心功能
sed(Stream EDitor)是無交互流編輯器,逐行讀取文本到臨時(shí)緩沖區(qū)(模式空間),根據(jù)指定命令處理文本,處理后輸出結(jié)果,默認(rèn)不修改原文件,主打文本的刪除、替換、添加、遷移。
基本語法
sed [選項(xiàng)] '處理命令' 目標(biāo)文件
核心特性
- 工作流程:讀取→執(zhí)行→顯示,循環(huán)直至文本處理完畢,緩沖區(qū)處理后清空,不影響原文件。
- 直接修改原文件:需加
-i選項(xiàng)(高危操作,建議先備份原文件)。 - 多命令執(zhí)行:用
-e選項(xiàng)分隔多個(gè)命令,如sed -e 's/a/b/g' -e '3d' test.txt。
常用選項(xiàng)與處理命令
常用選項(xiàng)
表格
| 選項(xiàng) | 功能說明 |
|---|---|
-n | 僅輸出處理后的匹配行,抑制默認(rèn)的整行輸出 |
-i | 直接修改原文件(建議先備份) |
-e | 執(zhí)行多個(gè)處理命令 |
-f | 從腳本文件中讀取處理命令 |
核心處理命令(行操作 + 字符操作)
表格
| 命令 | 功能說明 | 適用場景 |
|---|---|---|
p | 打印匹配行 | 結(jié)合-n輸出指定行 |
d | 刪除指定行 | 過濾空行、注釋行、指定行 |
s | 字符串替換 | 替換指定字符 / 字符串(核心) |
a | 行后添加 | 在指定行后插入新內(nèi)容 |
i | 行前插入 | 在指定行前插入新內(nèi)容 |
c | 整行替換 | 將指定行替換為新內(nèi)容 |
y | 字符轉(zhuǎn)換 | 按位轉(zhuǎn)換字符(如 a→A,b→B) |
經(jīng)典示例(附實(shí)用技巧)
# 打印操作:輸出test.txt的第3行,結(jié)合-n抑制默認(rèn)輸出 sed -n '3p' test.txt # 刪除操作:刪除test.txt中的空行和以#開頭的行 sed '/^$/d; /^#/d' test.txt # 替換操作:將test.txt中所有的the替換為THE(s/原字符串/新字符串/替換模式) sed 's/the/THE/g' test.txt # 替換模式補(bǔ)充:g=全局替換,2=替換每行第2個(gè),^=行首,$=行尾 sed 's/^/#/' test.txt # 所有行首加# sed 's/$/EOF/' test.txt # 所有行尾加EOF # 插入操作:在第5行后插入一行內(nèi)容“Hello Linux” sed '5a Hello Linux' test.txt # 直接修改原文件:將配置文件中的anonymous_enable=YES改為NO(FTP配置常用) sed -i 's/^anonymous_enable=YES/anonymous_enable=NO/' vsftpd.conf # 多命令執(zhí)行:刪除空行并替換the為THE sed -e '/^$/d' -e 's/the/THE/g' test.txt #將文件中的所有o刪除(替換為空串) sed 's/o//g' test.txt #在每行行首插入#號 sed 's/^/#/' test.txt
(1.遷移符號條件的文本
| 命令 | 參數(shù) |
| H | 復(fù)制到剪貼板 |
| g,G | 將剪貼板中的數(shù)據(jù)覆蓋/追加至指定行 |
| w | 保存為文件 |
| r | 讀取指定文件 |
| a | 追加指定內(nèi)容 |
#將包含the的行遷移至文件末尾,{;}用于多個(gè)操作
sed '/the/{H;d};$G' test.txt
#將第1~5行內(nèi)容轉(zhuǎn)移至第17行后
sed '1,5{H;d};17G' test.txt
#將包含the的行另存為文件out.file
sed '/the/w out.file' test.txt
#將文件/etc/hostname的內(nèi)容添加到包含the的每行以后
sed '/the/r /etc/hostname' test.txt
#在第3行后插入一個(gè)新行,內(nèi)容為New
sed '3aNew' test.txt
#在包含the的每行后插入一個(gè)新行,內(nèi)容為New
sed '/the/aNew' test.txt
#在第3行后插入多行內(nèi)容,中間的\n表示換行
sed '3aNew1\nNew2' test.txt(2.使用腳本編輯文件
使用sed腳本將多個(gè)編輯指令存放到文件中(每行一條編輯指令),通過“-f”選項(xiàng)來調(diào)用。
示例:執(zhí)行以下命令可將第1~5行內(nèi)容轉(zhuǎn)移至第17行后
sed '1,5{H;d];17g' test.txt
vim opt.list(創(chuàng)建)
sed opt.list test.txt(3.sed直接操作文件示例
編寫一個(gè)腳本,用來調(diào)整vsftpd服務(wù)配置,要求禁止匿名用戶,但允許本地用戶(也允許寫入) vim local_only_ftp.sh #!/bin/bash #指定樣本文件路徑,配置文件路徑 SAMPLE="/usr/share/doc/vsftpd-3.0.2/EXAMPLE/INTERNET_SITE/vsftpd.conf" CONFIG="/etc/vsftpd/vsftpd.conf #備份原來的配置文件,檢測文件名為/etc/vsftpd/vsftpd.conf.bak備份文件是否存在,若不存在,則創(chuàng)建 #存在則使用cp命令進(jìn)行文件備份 [ ! -e "$CONFIG.bak" ] && cp $CONFIG $CONFIG.bak #基于樣本配置進(jìn)行調(diào)整,覆蓋現(xiàn)有文件 sed -e '/^anonymous_enable/s/YES/NO/g' $SAMPLE > $CONFIG sed -i -e '/^local_enable/s/NO/YES/g' -e '/^write_enable/s/NO/YES/g' $CONFIG grep "listen" $CONFIG || sed -i "$alisten=YES' $CONFIG #啟動(dòng)vsftpd服務(wù),并設(shè)為開機(jī)后自動(dòng)運(yùn)行 systemctl restart vsftpd systemctl enable vsftpd
3. 文本分析:awk
核心功能
awk是一門輕量級的文本分析語言,核心特性是按字段分割文本,默認(rèn)以空格 / 制表符為分隔符,將每行分為多個(gè)字段($1、$2...$n),支持字段提取、數(shù)據(jù)統(tǒng)計(jì)、條件判斷、數(shù)學(xué)運(yùn)算,主打結(jié)構(gòu)化文本的分析與格式化輸出,最適合處理日志、/etc/passwd 等分隔符格式的文件。
基本語法
awk [選項(xiàng)] '條件{處理命令}' 目標(biāo)文件 核心特性
- 內(nèi)置變量:awk 提供了大量內(nèi)置變量,簡化文本處理,是 awk 的核心優(yōu)勢。
- BEGIN/END 模塊:
BEGIN{}在處理文本前執(zhí)行(如初始化變量、設(shè)置分隔符);END{}在處理文本后執(zhí)行(如統(tǒng)計(jì)結(jié)果輸出)。 - 字段分隔符:默認(rèn)空格 / 制表符,可通過
-F選項(xiàng)指定(如-F ":"以冒號為分隔符)。
核心內(nèi)置變量
表格
| 變量 | 功能說明 |
|---|---|
$0 | 表示當(dāng)前處理的整行內(nèi)容 |
$n | 表示當(dāng)前行的第 n 個(gè)字段(第 n 列) |
FS | 字段分隔符,等價(jià)于-F選項(xiàng) |
NF | 當(dāng)前行的字段總數(shù)(列數(shù)) |
NR | 當(dāng)前處理的行號(序數(shù)) |
FILENAME | 被處理的文件名 |
常用操作示例(附實(shí)用統(tǒng)計(jì)技巧)
# 基礎(chǔ)字段提?。阂悦疤枮榉指舴?,讀取/etc/passwd的用戶名($1)和用戶ID($3)
awk -F ":" '{print $1,$3}' /etc/passwd
# 行號與內(nèi)容結(jié)合:輸出test.txt的行號和對應(yīng)行內(nèi)容
awk '{print NR":"$0}' test.txt
# 條件過濾:輸出/etc/passwd中用戶ID為0的行(root用戶)
awk -F ":" '$3==0{print $1}' /etc/passwd
# 統(tǒng)計(jì)技巧:統(tǒng)計(jì)/etc/passwd中使用/bin/bash作為登錄Shell的用戶數(shù)(BEGIN初始化,END輸出結(jié)果)
awk -F ":" 'BEGIN{x=0};/\/bin\/bash$/{x++};END{print "有效用戶數(shù):"x}' /etc/passwd
# 格式化輸出:輸出test.txt中字段數(shù)大于3的行,按“行號-字段1-字段2”格式顯示
awk 'NF>3{print NR"-"$1"-"$2}' test.txt
# 調(diào)用Shell命令:輸出當(dāng)前主機(jī)名(awk中調(diào)用外部命令用""|getline)
awk 'BEGIN{"hostname"|getline;print $0}'三、三劍客工具的選型原則(補(bǔ)充核心知識點(diǎn))
實(shí)際應(yīng)用中,需根據(jù)文本處理的需求選擇合適的工具,避免過度使用復(fù)雜工具,以下為核心選型原則,快速匹配場景:
- 僅文本查找 / 過濾:優(yōu)先用
grep,速度最快,語法最簡單,適合快速匹配字符串 / 正則。 - 文本的行編輯(刪、替、加、移):優(yōu)先用
sed,按行處理效率高,適合無交互的批量文本編輯。 - 文本的字段分析 / 數(shù)據(jù)統(tǒng)計(jì):優(yōu)先用
awk,按字段分割的特性適合結(jié)構(gòu)化文本,支持統(tǒng)計(jì)、運(yùn)算、格式化,功能最強(qiáng)大。 - 組合使用:復(fù)雜場景可通過管道符(|) 組合三劍客,如
grep過濾行→sed編輯→awk分析統(tǒng)計(jì)。
組合示例:過濾 test.txt 中包含 the 的行,刪除行尾的小數(shù)點(diǎn),再輸出行號和內(nèi)容
grep 'the' test.txt | sed 's/\.$//g' | awk '{print NR":"$0}' 四、實(shí)戰(zhàn)應(yīng)用場景
- 配置文件優(yōu)化:過濾 nginx、vsftpd 等配置文件中的空行和注釋行,生成干凈的配置文件
grep -v '^$' nginx.conf | grep -v '^#' > nginx.conf.clean
- 日志分析:篩選 /var/log/messages 中包含 “error” 的錯(cuò)誤日志,顯示行號和時(shí)間
grep -n 'error' /var/log/messages | awk '{print $1,$2,$3,$0}' - 用戶管理:統(tǒng)計(jì) Linux 系統(tǒng)中普通用戶(UID≥1000)的數(shù)量
awk -F ":" '$3>=1000{x++};END{print "普通用戶數(shù):"x}' /etc/passwd - 文本替換:批量將當(dāng)前目錄下所有.sh 腳本中的 “oldstr” 替換為 “newstr”
sed -i 's/oldstr/newstr/g' *.sh
五、總結(jié)
- 正則表達(dá)式是文本匹配的基礎(chǔ),分為基礎(chǔ)和擴(kuò)展兩類,
grep默認(rèn)支持基礎(chǔ)正則,grep -E/egrep/awk支持?jǐn)U展正則,核心是掌握元字符的定位和匹配規(guī)則。 - Shell 三劍客各有側(cè)重:
grep查、sed編、awk析,搭配管道符可實(shí)現(xiàn)復(fù)雜文本處理。 - 實(shí)用技巧:
sed -i直接修改原文件需先備份;awk的 BEGIN/END 模塊是數(shù)據(jù)統(tǒng)計(jì)的核心;^$匹配空行、\<\>匹配單詞邊界是正則的高頻用法。 - 選型原則:簡單查找用 grep,行編輯用 sed,字段分析 / 統(tǒng)計(jì)用 awk,復(fù)雜場景組合使用。
掌握正則表達(dá)式與文本處理器的核心用法,能讓 Linux 下的文本處理工作事半功倍,也是編寫高效 Shell 腳本的基礎(chǔ),后續(xù)可通過實(shí)際場景的練習(xí),加深對工具的靈活運(yùn)用。
到此這篇關(guān)于Linux Shell編程之正則表達(dá)式與文本處理器用法詳解的文章就介紹到這了,更多相關(guān)Shell正則表達(dá)式與文本處理器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu) 二叉樹的遞歸與非遞歸
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu) 二叉樹的遞歸與非遞歸的相關(guān)資料,需要的朋友可以參考下2017-05-05
shell腳本實(shí)現(xiàn)Hbase服務(wù)的監(jiān)控報(bào)警和自動(dòng)拉起問題
這篇文章主要介紹了shell腳本實(shí)現(xiàn)Hbase服務(wù)的監(jiān)控報(bào)警和自動(dòng)拉起,主要是通過服務(wù)名監(jiān)控和端口監(jiān)控,通過企業(yè)微信消息通知腳本,對此內(nèi)容感興趣的朋友跟隨小編一起看看吧2022-11-11
Linux shell腳本實(shí)現(xiàn)CPU預(yù)警
這篇文章主要介紹了Linux shell腳本實(shí)現(xiàn)CPU預(yù)警的方法,并附上代碼以及用法,有需要的小伙伴可以參考下。2015-03-03
Linux C中sockaddr和sockaddr_in的區(qū)別
這篇文章主要介紹了Linux C中sockaddr和sockaddr_in的區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-07-07
shell 遞歸遍歷目錄下的所有文件并統(tǒng)一改名的方法
今天小編就為大家分享一篇shell 遞歸遍歷目錄下的所有文件并統(tǒng)一改名的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
linux 中的ls命令參數(shù)詳解及l(fā)s命令的使用實(shí)例
這篇文章主要介紹了linux 中的ls命令參數(shù)詳解及l(fā)s命令的使用實(shí)例,需要的朋友可以參考下2017-08-08

