一、正則表達式基礎
1. 正則表達式概述
?定義?:正則表達式(Regular Expression,簡稱Regex)是由普通字符?(如字母、數字、標點符號)與元字符?(具有特殊含義的專用字符)組成的字符串匹配規則,用于判斷某字符串是否符合特定格式要求。
?核心作用?:在Shell腳本中,通過文本處理工具(如grep
、sed
、awk
)結合正則表達式,可以快速篩選、提取或修改目標文本內容,是自動化運維、日志分析、數據清洗等場景的基礎技能。
?類比理解?:正則表達式類似于“文本搜索的精準模板”——普通字符按字面意義匹配,元字符則定義了匹配的“規則模式”(如“任意字符”“重復次數”“開頭/結尾位置”等)。
2. 正則表達式分類
根據POSIX(可移植操作系統接口)標準,正則表達式分為兩大類,主要區別在于元字符的語法格式(是否需要轉義)及支持的工具:
?類型? | ?支持工具? | ?核心區別? | ?典型使用場景? |
---|---|---|---|
?基本正則表達式(BRE,Basic Regular Expression)?? |
| 元字符(如 | 簡單文本過濾(如查找固定模式的行)。 |
?擴展正則表達式(ERE,Extended Regular Expression)?? |
| 元字符(如 | 復雜模式匹配(如分組、邏輯“或”操作)。 |
?關鍵區別示例?:
匹配連續2個
o
:
BRE(需轉義):
go\{2\}d
(如grep "go\{2\}d" file
)ERE(無需轉義):
go{2}d
(如egrep "go{2}d" file
或grep -E "go{2}d" file
)
?工具默認行為?:
grep
:默認使用BRE,若需使用ERE需加-E
參數(或直接使用egrep
)。sed
:默認使用BRE,若需使用ERE需加-r
參數(部分新版本支持-E
)。awk
:默認支持大部分ERE語法(如+
、?
、|
無需轉義)。
二、正則表達式核心元字符詳解
1. 通用元字符(BRE與ERE均適用)
這些元字符在基本正則和擴展正則中功能一致,但部分在BRE中需要轉義。
?元字符? | ?含義? | ?用法示例? | ?匹配示例? |
---|---|---|---|
| 匹配字符串的開頭位置? |
|
|
| 匹配字符串的結尾位置? |
|
|
| 匹配除換行符? | ||
之外的任意單個字符 |
|
| |
| 匹配前一個字符的0次或多次重復? |
|
|
`` | ?轉義字符,用于取消特殊字符的元字符含義(如讓 |
|
|
?注意?:在BRE(如默認
grep
/sed
)中,元字符如{
、}
、+
、?
、|
需通過\`轉義才具有特殊含義;而在ERE(如
egrep/
grep -E/
awk`)中,這些元字符通常無需轉義。
2. 字符集合匹配(指定字符范圍內的選擇)
用于匹配一組字符中的任意一個,或排除某些字符。
?元字符? | ?含義? | ?用法示例? | ?匹配示例? |
---|---|---|---|
| 匹配方括號內列出的任意一個字符?(字符列表)。 |
|
|
| 匹配不在方括號內的任意一個字符(取反集合)。 |
|
|
?示例?:
[0-9]{3}
:匹配連續3個數字(如123
)。
[^ ]
:匹配非空格的任意字符(如字母、符號)。
3. 次數匹配(控制前一個字符的重復次數)
用于精確控制某個字符或字符集合的重復次數范圍。
?元字符? | ?含義? | ?用法示例? | ?匹配示例? |
---|---|---|---|
| 匹配前一個字符恰好n次?(BRE需轉義,ERE可直接用 |
|
|
| 匹配前一個字符至少n次?(BRE需轉義,ERE可直接用 |
|
|
| 匹配前一個字符n到m次?(BRE需轉義,ERE可直接用 |
|
|
?關鍵區別?:
在BRE(如默認
grep
/sed
)中,{
和}
是普通字符,需轉義為\{
和\}
才能表示次數匹配。在ERE(如
egrep
/grep -E
/awk
)中,直接使用{n}
、{n,}
等無需轉義。
?示例對比?:
BRE命令:
grep "go\{2\}d" file
(匹配gooood
)。ERE命令:
egrep "go{2}d" file
或grep -E "go{2}d" file
(效果相同,無需轉義)。
4. 擴展正則表達式特有元字符(僅ERE支持)
擴展正則表達式在BRE基礎上增加了更靈活的操作符,簡化了復雜模式的編寫。
?元字符? | ?含義? | ?用法示例? | ?匹配示例? |
---|---|---|---|
| 匹配前一個字符1次或多次?(至少1次,相當于 |
|
|
| 匹配前一個字符0次或1次?(最多1次,相當于 |
|
|
| 將括號內的內容視為一個整體?(用于分組操作,如重復、邏輯或)。 |
|
|
` | ` | 邏輯“或”匹配(匹配多個模式中的任意一個,類似“或”關系)。 |
|
?注意?:
()
和|
在BRE中無效(除非使用\(\)
和\|
轉義),僅在ERE中直接支持。
三、正則表達式核心元字符速查表
?類別? | ?元字符? | ?功能? | ?是否需要轉義(BRE)?? | ?ERE中是否轉義? |
---|---|---|---|---|
位置匹配 |
| 行首 | 否 | 否 |
| 行尾 | 否 | 否 | |
單字符匹配 |
| 任意單個字符(除` | ||
`) | 否 | 否 | ||
`` | 轉義特殊字符 | 是(需轉義其他元字符) | 是(按需轉義) | |
字符集合 |
| 匹配列表中的任意一個字符 | 否 | 否 |
| 匹配不在列表中的任意一個字符 | 否 | 否 | |
次數匹配 |
| 前一個字符0次或多次 | 否 | 否 |
| 前一個字符恰好n次(BRE) | 是(需加``) | 否(直接 | |
| 前一個字符至少n次(BRE) | 是(需加``) | 否(直接 | |
| 前一個字符n到m次(BRE) | 是(需加``) | 否(直接 | |
| 前一個字符恰好n次(ERE) | 否(ERE無需轉義) | 否 | |
擴展功能 |
| 前一個字符1次或多次 | 否(僅ERE支持) | 否 |
| 前一個字符0次或1次 | 否(僅ERE支持) | 否 | |
| 分組(整體操作) | 否(僅ERE支持) | 否 | |
` | `(ERE) | 邏輯“或”匹配 | 否(僅ERE支持) |
四、正則表達式實戰案例
案例1:電話號碼匹配(BRE)
?需求?:匹配區號025
開頭的電話號碼,要求:
號碼與區號間分隔符為空格、
-
或無分隔;號碼本身必須是5或8開頭,且為8位數字。
?正則表達式?:^(025)[ -]?[58][0-9]{7}$
?分解說明?:
^
:匹配行首;(025)
:匹配固定區號025
(分組非必須,但提高可讀性);[ -]?
:匹配分隔符(空格或-
),?
表示該分隔符出現0次或1次(即可以沒有分隔符);[58]
:匹配號碼首數字為5
或8
;[0-9]{7}
:匹配后續7位數字(共8位);$
:匹配行尾。
?測試數據(phone.txt)??:
02588888888
025-5555555555
025 12345678
025 54321678
025ABC88888
025-85432109
028-85643210
0251-52765421
?匹配命令?:
egrep "^(025)[ -]?[58][0-9]{7}$" phone.txt
?預期輸出?:
02588888888
025 54321678
025-85432109
案例2:電子郵箱匹配(ERE)
?需求?:匹配符合標準格式的郵箱(用戶名@子域名.二級域名.頂級域
),要求:
用戶名:6-18位,以字母或下劃線開頭,允許字母、數字、部分符號(不含
@
和空格);子域名與二級域名:允許字母、數字、
-
、_
、.
;頂級域:2-5位字母。
?正則表達式?:^([a-zA-Z_][^@ ]{5,17})@[a-zA-Z0-9_\-.]+(\.[a-zA-Z0-9_\-.]+)?\.([a-zA-Z]{2,5})$
?分解說明?:
^
:行首;([a-zA-Z_][^@ ]{5,17})
:用戶名部分:[a-zA-Z_]
:首字符為字母或下劃線;[^@ ]{5,17}
:后續5-17位為非@
、非空格的任意字符(總長度6-18位);
@
:固定符號;[a-zA-Z0-9_\-.]+
:子域名/二級域名(允許字母、數字、_
、-
、.
,至少1個字符);(\.[a-zA-Z0-9_\-.]+)?
:可選的二級域名(以.
開頭,后接合法字符,?
表示0或1次);\.([a-zA-Z]{2,5})
:頂級域(以.
開頭,后接2-5位字母);$
:行尾。
?測試數據(email.txt)??:
zhangsan123@qq.com
li si@163.com
wang@wu@sina.com
zhao liu@126.com
qianqi@sina.com.cn
?匹配命令?:
egrep "^([a-zA-Z_][^@ ]{5,17})@[a-zA-Z0-9_\-.]+(\.[a-zA-Z0-9_\-.]+)?\.([a-zA-Z]{2,5})$" email.txt
?預期輸出?:
zhangsan123@qq.com
qianqi@sina.com.cn
五、文本處理工具詳解
1. sed流編輯器(Stream Editor)
(1)核心概念
?sed是一種非交互式流編輯器,它逐行讀取輸入文本(文件或管道),根據預定義的規則(命令)對每行內容進行編輯(如刪除、替換、插入),并將結果輸出到屏幕或文件。?默認情況下,sed不會修改原文件?(除非使用-i
選項)。
?工作流程?:
?讀取?:從輸入源(文件/標準輸入)讀取一行內容,存入模式空間(臨時緩沖區);
?執行?:在模式空間中按順序執行所有sed命令(若指定行地址,則只對該行或行范圍執行);
?顯示?:將處理后的模式空間內容輸出到結果流(默認輸出到屏幕),然后清空模式空間;
?循環?:重復上述步驟,直到處理完所有輸入行。
?特點?:適合批量處理文本(如日志清洗、配置文件修改),尤其擅長基于行或模式的簡單編輯操作。
(2)常用命令格式
sed [選項] '操作命令' 文件1 文件2...
# 常用選項:
# -n:禁止默認輸出(僅顯示顯式指定的內容,需配合p命令使用)
# -i:直接修改原文件(謹慎使用!建議先備份)
# -r 或 -E:支持擴展正則表達式(-r為舊版,-E為新版推薦)
# -e:指定多個操作命令(單命令時可省略)
(3)常用操作與示例
?操作? | ?功能? | ?示例命令? | ?詳細說明? |
---|---|---|---|
| 打印當前模式空間的內容 |
| 需配合 |
| 刪除當前行 |
| 直接移除匹配的行,不進入輸出流。 |
| 替換字符 |
|
|
| 在當前行后追加內容 |
| 追加的文本會作為新行出現在指定行之后。 |
| 在當前行前插入內容 |
| 插入的文本會作為新行出現在指定行之前。 |
| 打印當前行號 |
| 僅輸出行號,不輸出行內容。 |
| 讀取下一行 |
|
|
(4)尋址方式(指定操作的目標行)
sed支持通過行號或正則表達式指定需要操作的行范圍。
?尋址方式? | ?示例命令? | ?說明? |
---|---|---|
?單行行號? |
| 精確操作某一行。 |
?最后一行? |
|
|
?行范圍? |
| 操作從起始行到結束行的所有行。 |
?相對行范圍? |
| 從指定行開始,連續操作后續N行。 |
?正則匹配行? |
| 操作所有匹配正則表達式的行。 |
?組合條件? |
| 從指定行開始,到匹配某個模式的行結束。 |
(5)高級操作示例
?刪除空行?:
sed '/^$/d' file.txt # 刪除所有空白行(行內容為空)
?注釋特定行?(如給以
root
開頭的行添加#
注釋):sed '/^root/ s/^/#/' /etc/passwd # 將/etc/passwd中以root開頭的行首添加#
?直接修改文件?(謹慎使用!):
sed -i 's/old/new/g' file.txt # 將文件中所有old替換為new,并直接保存到原文件
?復雜替換(保留匹配內容)??:
sed -n 's/\/bin\/bash/\/bin\/csh/p' /etc/passwd # 將/bin/bash替換為/bin/csh,并打印修改的行 # 使用\轉義/,或改用其他分隔符(如|)避免沖突: sed -n 's|/bin/bash|/bin/csh|p' /etc/passwd
2. awk文本分析工具(Pattern-Scan Processing Language)
(1)核心概念
?awk是一種面向字段的文本處理工具,它逐行讀取輸入文本,默認以空格或Tab鍵為分隔符將每行拆分為多個字段(1,2, ..., $NF),并通過模式(條件)+ 操作(命令)?的方式對符合條件的行進行靈活處理。awk更適合處理結構化數據(如日志、CSV文件),支持復雜的邏輯判斷、數學運算和循環控制。
?特點?:擅長按字段提取、統計和分析文本(如計算平均值、篩選特定條件的行、格式化輸出)。
(2)基本語法
awk [選項] '模式或條件 {操作語句}' 文件1 文件2...
# 常用選項:
# -F:指定字段分隔符(如-F: 表示以冒號為分隔符)
?執行流程?:
逐行讀取輸入文本;
根據指定的分隔符(默認空格/TAB)將當前行拆分為多個字段(1,2,...NF,0表示整行);
若未指定模式,則對所有行執行操作;若指定了模式(如
/關鍵詞/
、NR>10
),則僅對匹配模式的行執行操作;在操作語句中,可通過內置變量(如$1、NF、NR)訪問字段和行信息,并執行打印、計算等操作。
(3)常用內置變量
?變量? | ?含義? | ?示例? |
---|---|---|
| 當前行的完整內容 |
|
| 當前行的第1~n個字段 |
|
| 當前行的字段總數 |
|
| 當前處理的行號(從1開始) |
|
| 輸入字段分隔符(同-F選項) |
|
| 輸出字段分隔符(默認空格) | `awk '{OFS=" |
(4)常用操作與示例
?場景? | ?命令示例? | ?詳細說明? |
---|---|---|
?打印所有內容? |
| 打印文件的每一行($0表示整行內容)。 |
?打印指定行? |
| 通過行號(NR)精確控制要輸出的行。 |
?打印行范圍? |
| 操作從第1行到第3行的所有內容。 |
?打印奇數行/偶數行? | 奇數行: | 通過取模運算(NR%2)判斷行號的奇偶性。 |
?按字段篩選? |
| 條件判斷字段值(如第3字段UID),并輸出指定字段。 |
?統計匹配行數? |
|
|
?格式化輸出? |
| 自定義輸出格式(結合字符串拼接)。 |
?多分隔符支持? |
| 方括號內指定多個分隔符(邏輯“或”關系)。 |
(5)高級功能
?調用Shell命令?:通過管道將字段傳遞給外部命令(如統計在線用戶數):
awk 'BEGIN{n=0; while("w" | getline) n++; print n-2}' # 統計當前登錄用戶數(扣除標題和空行)
?數學運算?:計算某列的平均值(如第一列數字的平均值):
awk '{sum+=$1; count++} END {print sum/count}' data.txt # sum累加第一列,count統計行數
?數組統計?:統計每行首字段的出現次數并排序:
awk '{a[$1]++} END {for(i in a) print a[i],i}' test.txt # 統計每個首字段的出現次數 awk '{a[$1]++} END {for(i in a) print a[i],i}' test.txt | sort -r # 按次數降序排序
?條件判斷與三元運算符?:
awk -F: '{max=($3>$4)?$3:$4; print max}' /etc/passwd # 取第3字段和第4字段的最大值
?內置函數?:如
length($0)
(計算行長度)、tolower($1)
(轉小寫)、substr($1,2,3)
(截取子串)。
六、總結對比
?工具? | ?核心定位? | ?主要功能? | ?正則表達式支持? | ?典型使用場景? |
---|---|---|---|---|
| 快速文本搜索與過濾 | 根據模式匹配查找包含特定內容的行(支持過濾日志、查找關鍵字) | BRE(默認)、ERE( | 日志分析、關鍵詞查找、空行/注釋過濾 |
| 流式文本編輯 | 對文本行進行刪除、替換、插入等操作(適合批量修改配置文件、清理日志) | BRE(默認)、ERE( | 配置文件修改、行內容替換、注釋處理 |
| 結構化文本分析與處理 | 按字段拆分文本,支持條件判斷、數學運算、復雜邏輯(適合數據統計、報表生成) | ERE(默認支持高級正則) | 日志統計、字段提取、數據格式化 |