Shell編程之正則表達(dá)式與文本怎么用
一 正則表達(dá)式
1 正則表達(dá)式的定義
正則表達(dá)式(Regular Expression,簡稱 regex 或 regexp)是一種用于描述字符串匹配規(guī)則的文本模式。它由普通字符(如字母、數(shù)字)和元字符(特殊符號)組成,通過特定的語法規(guī)則實(shí)現(xiàn)對字符串的搜索、匹配、替換或提取等操作。
核心特點(diǎn):
是一種迷你語言,獨(dú)立于編程語言(但各語言實(shí)現(xiàn)可能有細(xì)微差異)。
通過模式(pattern)匹配文本,而非直接比較字符串。
2 正則表達(dá)式用途
正則表達(dá)式的主要應(yīng)用場景包括:
| 用途 | 說明 | 示例 |
|---|---|---|
| 文本搜索 | 快速查找符合特定規(guī)則的字符串(如郵箱、電話號碼)。 | 在日志中查找所有錯誤代碼 ERROR:\d+。 |
| 數(shù)據(jù)驗(yàn)證 | 驗(yàn)證用戶輸入格式(如密碼強(qiáng)度、郵箱合法性)。 | 檢查密碼是否包含大小寫和數(shù)字 ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$。 |
| 文本替換 | 批量替換符合規(guī)則的文本(如敏感詞過濾、格式調(diào)整)。 | 將日期格式從 MM/DD/YYYY 替換為 YYYY-MM-DD。 |
| 字符串提取 | 從復(fù)雜文本中提取特定部分(如網(wǎng)頁中的URL、文件中的關(guān)鍵詞)。 | 提取HTML中的鏈接 href="(.*?)"。 |
| 文本分割 | 按規(guī)則拆分字符串(如CSV文件按分隔符分列)。 | 按逗號或分號分割 [,;]。 |
| 日志分析 | 解析結(jié)構(gòu)化日志數(shù)據(jù)(如提取時間戳、IP地址)。 | 匹配IP地址 \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b。 |
| 代碼處理 | 在IDE或編輯器中批量重構(gòu)代碼(如重命名變量、調(diào)整格式)。 | 替換所有 var 為 let。 |
關(guān)鍵記憶點(diǎn):
定義:用模式描述字符串規(guī)則的文本工具。
用途:搜索、驗(yàn)證、替換、提取、分割文本。
核心價值:高效處理復(fù)雜的字符串操作,減少手動編碼。
二 正則表達(dá)式類型
1 基礎(chǔ)正則表達(dá)式示例
| 語法 | 說明 | 示例 |
|---|---|---|
| 查找特定字符 | 直接匹配指定的字符或字符串。 | "hello" 匹配文本中的 hello。 |
| 中括號 [] | 匹配括號內(nèi)的任意一個字符(字符集合)。 | [aeiou] 匹配任意一個元音字母。 |
| 行首 ^ 和行尾 $ | ^ 匹配行首,$ 匹配行尾。 | ^Hello 匹配以 Hello 開頭的行。 |
| 任意字符 . 和重復(fù)字符 * | . 匹配任意單個字符(除換行符),* 匹配前一個字符 0 次或多次。 | h.*o 匹配 hello、halo 等。 |
| 連續(xù)字符范圍 {} | {n} 匹配前一個字符 n 次,{n,m} 匹配 n 到 m 次。 | a{2,4} 匹配 aa、aaa、aaaa。 |
以下是正則表達(dá)式的語法:
(1)查找特定字符
語法:
grep -n [ 參數(shù) ] 文本 //查找文本行號
grep -nv [ 參數(shù) ] 文本 //查找文本行號相反的參數(shù)
語法示例:

(2)利用中括號” [] “來查找集合字符
范圍表示法:
[a-z]:匹配任意小寫字母。
[A-Z]:匹配任意大寫字母。
[0-9]:匹配任意數(shù)字。組合范圍:
[a-zA-Z0-9]匹配所有字母和數(shù)字。
特殊字符轉(zhuǎn)義:
在
[]內(nèi),大多數(shù)特殊字符(如.、*)會失去特殊含義,無需轉(zhuǎn)義。但以下字符需注意:
^:僅在開頭表示排除,其他位置作為普通字符。-:表示范圍時(如a-z),需放在開頭或結(jié)尾避免歧義。]:需用\]轉(zhuǎn)義或放在開頭。
語法示例:

(3)查找行首字符” ^ “與行尾字符”$“
語法:
行首字符” ^ “
^匹配一行的開頭位置(在行首之前的位置)。通常用于確保模式出現(xiàn)在行首。
行尾字符”$“
$匹配一行的結(jié)尾位置(在行末換行符之前的位置)。通常用于確保模式出現(xiàn)在行尾。
語法示例:
grep '^hello' file.txt # 查找以 "hello" 開頭的行
grep -v '^#' file.txt # 查找不以 `#` 開頭的行(常用于過濾注釋行)
grep 'world$' file.txt # 查找以 "world" 結(jié)尾的行
grep '^[A-Z]' file.txt # 查找以大寫字母開頭的行
grep '[0-9]$' file.txt # 查找以數(shù)字結(jié)尾的行
(4)查找任意一個字符” .“ 與重復(fù)字符”*“
在正則表達(dá)式中,.(點(diǎn))和 *(星號)是兩個核心元字符,分別用于匹配任意單個字符和重復(fù)前一個字符/模式。
語法示例:
grep -n 'w..d' test.txt
grep -n 'ooo*' test.txt
grep -n 'woo*d' test.txt
(5)查找連續(xù)字符范圍”{}“
在正則表達(dá)式中,大括號 {} 用于指定 前一個字符或模式的重復(fù)次數(shù),是精確控制匹配數(shù)量的重要工具。
語法示例:
# grep (BRE):需轉(zhuǎn)義
echo "aaa" | grep 'a\{2\}'# grep (ERE):免轉(zhuǎn)義
echo "aaa" | grep -E 'a{2}'# sed (BRE):需轉(zhuǎn)義
echo "aaa" | sed -n '/a\{2\}/p'# sed (ERE):免轉(zhuǎn)義
echo "aaa" | sed -E -n '/a{2}/p'
2 元字符總結(jié)
| 元字符 | 含義 |
|---|---|
. | 匹配任意單個字符(除換行符 \n)。 |
^ | 匹配行首(在 [] 內(nèi)表示取反,如 [^a] 匹配非 a 的字符)。 |
$ | 匹配行尾。 |
* | 匹配前一個字符 0 次或多次(貪婪匹配)。 |
+ | 匹配前一個字符 1 次或多次(需在擴(kuò)展正則中使用)。 |
? | 匹配前一個字符 0 次或 1 次(也可用于非貪婪匹配,如 .*?)。 |
{n} | 匹配前一個字符 恰好 n 次。 |
{n,} | 匹配前一個字符 至少 n 次。 |
{n,m} | 匹配前一個字符 n 到 m 次。 |
[] | 匹配括號內(nèi)的任意一個字符,如 [a-z] 匹配任意小寫字母。 |
| | | 或 匹配(需在擴(kuò)展正則中使用),如 `cat dog |
() | 分組匹配,可用于提取或應(yīng)用量詞,如 (ab)+ 匹配 ab、abab 等。 |
\ | 轉(zhuǎn)義字符,用于匹配特殊字符本身,如 \. 匹配 .,\* 匹配 *。 |
3 擴(kuò)展正則表達(dá)式
擴(kuò)展正則表達(dá)式在基礎(chǔ)正則(BRE)上增加了更強(qiáng)大的功能,通常需要加 -E 選項(xiàng)(如 grep -E 或 egrep)。
| 擴(kuò)展功能 | 說明 | 示例 |
|---|---|---|
+ | 匹配前一個字符 1 次或多次(BRE 中需用 \{1,\})。 | go+l 匹配 gol、gooool。 |
? | 匹配前一個字符 0 次或 1 次(BRE 中需用 \{0,1\})。 | colou?r 匹配 color 或 colour。 |
| | | `或 匹配,可組合多個模式。 | `cat dog匹配cat或dog`。 |
() | 分組匹配,支持捕獲組和反向引用。 | (ab)+ 匹配 abab、ab 等。 |
\d, \w, \s | 預(yù)定義字符類(部分工具支持):\d 數(shù)字,\w 單詞字符,\s 空白符。 | \d{3} 匹配 123、456 等。 |
4 擴(kuò)展正則表達(dá)式和基礎(chǔ)正則表達(dá)式的對比總結(jié)
| 特性 | 基礎(chǔ)正則表達(dá)式(BRE) | 擴(kuò)展正則表達(dá)式(ERE) | 說明 |
|---|---|---|---|
| 量詞 | *, \{n,m\} | *, +, ?, {n,m} | ERE 支持更簡潔的量詞寫法,BRE 需轉(zhuǎn)義 {}。 |
| 或匹配 | | 不支持(需 | 轉(zhuǎn)義) | 支持 | ERE 可直接使用 | 表示“或”關(guān)系,BRE 需 `\ |
| 分組 () | \( \)(需轉(zhuǎn)義) | ()(直接使用) | ERE 分組無需轉(zhuǎn)義,BRE 需寫成 \(...\)。 |
| 行首/行尾 | ^, $ | ^, $ | 兩者相同。 |
| 字符集 [] | 支持 | 支持 | 兩者相同。 |
| 非貪婪匹配 | 不支持(默認(rèn)貪婪) | 支持 *?, +? | ERE 可用 ? 實(shí)現(xiàn)非貪婪匹配,BRE 無此功能。 |
| 預(yù)定義字符類 | 部分支持(如 \w 依賴工具) | 更廣泛支持(如 \d, \s) | ERE 在某些工具(如 grep -P)支持 Perl 風(fēng)格正則。 |
| 適用工具 | grep, sed(默認(rèn)) | grep -E, egrep, awk, Perl, Python | ERE 更現(xiàn)代,BRE 主要用于傳統(tǒng) Unix 工具。 |
關(guān)鍵區(qū)別:
語法簡潔性
ERE 的
+,?,|,()等無需轉(zhuǎn)義,BRE 需用\+,\?,\|,\(\)。例如匹配
color或colour:BRE:
colou\?rERE:
colou?r
功能擴(kuò)展性
ERE 支持非貪婪匹配(
.*?)、或運(yùn)算(|)、更靈活的量詞,BRE 功能受限。
工具兼容性
BRE 是傳統(tǒng) Unix 工具(如
grep、sed)的默認(rèn)模式,ERE 需通過-E選項(xiàng)或egrep啟用。現(xiàn)代語言(如 Python、Perl)默認(rèn)使用 ERE 或更強(qiáng)大的正則引擎(PCRE)。
如何選擇?
使用 BRE:兼容老舊腳本或必須使用
sed/grep默認(rèn)模式時。使用 ERE:需要更簡潔的語法和高級功能(如
|、+)時,優(yōu)先選擇grep -E或awk。
一句話總結(jié):ERE 是 BRE 的增強(qiáng)版,語法更簡潔、功能更強(qiáng)大,但需注意工具兼容性。
三 文本處理器
1 sed工具
sed(Stream Editor)是一個強(qiáng)大的流式文本編輯器,主要用于對文本進(jìn)行查找、替換、刪除、插入等操作,支持正則表達(dá)式,適合批量處理文本。
sed的工作流程主要包括讀取,執(zhí)行和顯示三個過程:
讀取:將
"hello world"讀入模式空間。執(zhí)行:依次執(zhí)行替換命令 →
"Hi world"→"Hi universe"。顯示:輸出最終結(jié)果
"Hi universe"。
sed語法:
sed [ 選項(xiàng) ] “操作” 參數(shù)
sed [ 選項(xiàng) ] -f scriptfile 參數(shù)
常見的sed命令選項(xiàng)主要包含以下幾種:
| 選項(xiàng) | 作用 |
| -e (編輯腳本) | 指定要執(zhí)行的編輯命令(可多次使用,連接多個命令) |
| -f (從文件讀取腳本) | 表使用指定的腳本文件來處理輸入的文本文件 |
-h 或 --help | 顯示幫助 |
| -n (靜默模式) | 表示僅顯示處理后的結(jié)果 |
| -i (直接修改文件) | 直接編輯源文件(謹(jǐn)慎使用,建議先備份或測試) |
| -r (擴(kuò)展正則表達(dá)式) | 啟用擴(kuò)展正則表達(dá)式 |
| -l (行緩沖輸出) | 指定輸出行的長度(通常用于特殊設(shè)備或格式化) |
(1)輸出符合條件的文本(p表示正常輸出)
在正則表達(dá)式和文本處理工具(如 grep、sed、awk)中,p 命令 或 print 動作 用于 顯式輸出符合條件的文本,通常與條件匹配結(jié)合使用。
語法示例:
grep 'pattern' file.txt # 輸出包含 'pattern' 的整行
grep -o 'pattern' file.txt # 僅輸出匹配 'pattern' 的部分
grep -Po 'pattern' file.txt # 支持 Perl 兼容正則(如非貪婪匹配 `.*?`)
sed -n '/pattern/p' file.txt # 僅輸出匹配 'pattern' 的行(`-n` 抑制默認(rèn)輸出)
(2)刪除符合條件的文本(d)
在文本處理工具(如 sed、awk、grep)中,d 命令 或 delete 動作 用于 刪除符合條件的文本行。
語法示例:
sed '/pattern/d' file.txt # 刪除匹配 `pattern` 的行
sed '1,3d' file.txt # 刪除第1~3行
sed '$d' file.txt # 刪除最后一行sed '/pattern/!d' file.txt # 刪除不匹配 `pattern` 的行(即保留匹配行)
sed -i '/error/d' log.txt # 直接刪除文件中的錯誤行(原文件被修改)
awk '!/pattern/' file.txt # 刪除匹配 `pattern` 的行(`!` 表示否定)
awk 'NR>3' file.txt # 刪除前3行(保留行號大于3的行)
(3)替換符合條件的文本
在文本處理中,替換符合條件的文本是核心操作之一,主要通過 sed、awk、grep(結(jié)合其他工具)等實(shí)現(xiàn)。
語法示例:
sed 's/原內(nèi)容/替換內(nèi)容/[flags]' file.txt
s:替換命令flags常用選項(xiàng):g:全局替換(一行中所有匹配)。i:忽略大小寫(如s/pattern/replace/i)。p:打印替換成功的行(需與-n配合)。
echo "hello world" | sed 's/world/China/' # 輸出:hello China
echo "a b a" | sed 's/a/A/g' # 全局替換:A b A
sed -i 's/foo/bar/g' file.txt # 直接修改文件sed '2s/old/new/' file.txt # 僅替換第2行的內(nèi)容
echo "2023-10-01" | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)/\2\/\1/'
# 輸出:10/2023-01(分組重組)sed '/error/s/foo/bar/' file.txt # 僅在含 "error" 的行替換
(4)遷移符合條件的文本
作用:在指定位置插入、追加、替換或讀取外部文件內(nèi)容。
| 命令 | 說明 | 示例 |
|---|---|---|
i | 在匹配行前插入 | sed '/pattern/i\new line' file |
a | 在匹配行后追加 | sed '/pattern/a\new line' file |
c | 替換匹配行 | sed '/pattern/c\replacement' file |
r | 讀取文件并插入 | sed '/pattern/r otherfile' file |
w | 將匹配行寫入文件 | sed '/pattern/w output.txt' file |
語法示例:

(5)使用腳本編輯文件
以下是關(guān)于 使用腳本編輯文件 的全面總結(jié),涵蓋常用工具(sed、awk、perl 等)、核心操作(替換、刪除、插入)
語法示例:
sed -i 's/old/new/g' file.txt # 全局替換
sed '/pattern/s/old/new/' file.txt # 僅替換匹配行awk '{gsub(/old/, "new"); print}' file.txt > tmp && mv tmp file.txt
perl -pi -e 's/old/new/g' file.txt # 直接修改文件
(6)sed直接操作文件示例
#!/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備份文件是否存在,若不存在則使用cp命令進(jìn)行文件備份
[ ! -e "$CONFIG.bak" ]&& cp $CONFIG $CONFIG.bak
#基于樣本配置進(jìn)行調(diào)整,覆蓋現(xiàn)有文件

2 awk工具
awk 是一種強(qiáng)大的文本處理工具,擅長按行和列處理結(jié)構(gòu)化數(shù)據(jù)(如日志、CSV 文件),支持變量、條件判斷、循環(huán)等編程特性。
awk常用變量:
| 變量 | 含義 | 示例 |
|---|---|---|
NR | 當(dāng)前行號 | awk 'NR==1 {print}'(輸出第 1 行) |
NF | 當(dāng)前行的列數(shù) | awk '{print NF}'(輸出每行列數(shù)) |
FS | 輸入字段分隔符(默認(rèn)空格) | awk -F':' '{print $1}' |
OFS | 輸出字段分隔符(默認(rèn)空格) | awk 'BEGIN {OFS="-"}{print $1,$2}' |
FILENAME | 當(dāng)前文件名 | awk '{print FILENAME}' |
awk語法:
awk [選項(xiàng)] '模式 {動作}' 文件名
- 選項(xiàng):
awk支持一些選項(xiàng),如-F用于指定字段分隔符。 - 模式:用于匹配輸入行的條件,可以是正則表達(dá)式、比較表達(dá)式等。如果省略模式,則默認(rèn)匹配所有行。
- 動作:在匹配到的行上執(zhí)行的操作,通常是一系列的
awk語句,用花括號{}括起來。 - 文件名:要處理的輸入文件。如果省略文件名,則從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)。
(1)按行輸出文本
語法示例:
若要輸出一個文件的所有行,可使用 print 語句,它會默認(rèn)輸出當(dāng)前行。示例命令如下:
awk '{print}' filename.txt
在這個命令里,{print} 是 awk 的動作部分,print 函數(shù)會打印當(dāng)前處理的行。filename.txt 是你要處理的文件名。若要從標(biāo)準(zhǔn)輸入讀取內(nèi)容,可省略文件名,直接輸入文本并按 Ctrl + D 結(jié)束輸入。
awk '/^hello/ {print}' filename.txt
(2)按字段輸出文本
awk默認(rèn)以空格或制表符作為字段分隔符,使用$n來表示第n個字段(n是從 1 開始的正整數(shù)),$0表示整行內(nèi)容。
語法示例:
awk '{print $1}' data.txt //輸出每行的第一個字段
awk '{print $1, $3}' data.txt //輸出每行的第一個和第三個字段
awk -F ',' '{print $2}' info.csv //以逗號作為分隔符,輸出每行的第二個字段
awk -F ',' 'NR > 1 {printf "%-10s %d\n", $2, $3}' info.csv
//以固定寬度輸出名字和年齡
(3)通過管道,雙引號調(diào)用shell命令
awk流量控制:
| 語法 | 示例 | 說明 |
|---|---|---|
BEGIN{} | awk 'BEGIN {print "Start"}{print}' | 處理前執(zhí)行 |
END{} | awk '{sum+=$1} END {print sum}' | 處理后執(zhí)行 |
if 條件 | awk '{if($1>10) print $0}' | 條件判斷 |
for 循環(huán) | awk '{for(i=1;i<=NF;i++) print $i}' | 遍歷列 |
語法:
{
# 要執(zhí)行的 awk 操作
command = "shell 命令"
print $1 | command
close(command)
}
這里的 print $1 是把 $1 字段的內(nèi)容通過管道傳遞給 command 所代表的 shell 命令。使用完管道后,需要用 close(command) 來關(guān)閉它,防止出現(xiàn)文件描述符泄漏的問題。
3 sed工具和awk工具的對比總結(jié)
sed 和 awk 是 Linux/Unix 中兩大經(jīng)典文本處理工具,雖然功能有部分重疊,但設(shè)計(jì)目標(biāo)和適用場景差異顯著。以下是它們的對比總結(jié):
設(shè)計(jì)定位:
| 工具 | 核心定位 | 適用場景 |
|---|---|---|
sed | 流編輯器(Stream Editor) | 以行為單位的文本替換、刪除、插入等簡單編輯操作。 |
awk | 模式掃描與處理語言(AWK Language) | 基于列/字段的復(fù)雜數(shù)據(jù)處理、計(jì)算、報(bào)表生成等。 |
核心功能對比:
| 特性 | sed | awk |
|---|---|---|
| 處理單位 | 按行處理(默認(rèn)操作單位是整行) | 按行處理,但可拆分字段(默認(rèn)以空格/制表符分列) |
| 編程能力 | 支持簡單命令,無變量和算術(shù)運(yùn)算 | 支持變量、數(shù)組、循環(huán)、條件判斷、函數(shù)等完整編程特性 |
| 文本替換 | 強(qiáng)項(xiàng)(s/old/new/ 語法高效) | 支持替換,但語法不如 sed 簡潔 |
| 字段處理 | 弱(需依賴正則表達(dá)式截取字段) | 強(qiáng)(直接通過 $1, $2 訪問列) |
| 輸出控制 | 簡單輸出或靜默模式(-n + p) | 靈活格式化輸出(printf, print) |
| 多行處理 | 有限(需借助保持空間/模式空間技巧) | 更靈活(可通過變量緩存多行數(shù)據(jù)) |
如何選用:
用 sed 如果:
只需簡單的行級編輯(如替換、刪除)。
處理大文件時追求更高性能。
用 awk 如果:
需要按列處理數(shù)據(jù)或數(shù)學(xué)計(jì)算。
任務(wù)涉及條件判斷、循環(huán)或復(fù)雜邏輯。
到此這篇關(guān)于Shell編程之正則表達(dá)式與文本怎么用的文章就介紹到這了,更多相關(guān)Shell正則表達(dá)式與文本內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
linux shell中curl 發(fā)送post請求json格式問題的處理方法
這篇文章主要介紹了linux shell中curl 發(fā)送post請求json格式問題的處理方法,文中給大家提到了linux中使用curl發(fā)送post請求問題,需要的朋友可以參考下2018-07-07
Linux 中shell腳本設(shè)置開頭固定格式的實(shí)現(xiàn)方法
這篇文章主要介紹了Linux 中shell腳本設(shè)置開頭固定格式的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10
linux shell進(jìn)度條實(shí)現(xiàn)方法
linux shell實(shí)現(xiàn)的一咱進(jìn)度條,代碼很簡單,供大家參考2013-11-11

