通配符與正則表達式
通配符(Globbing)
通配符是由 Shell 處理的特殊字符,用于路徑或文件名匹配。當 Shell 在命令參數中遇到通配符時,會將其擴展為匹配的文件路徑;若沒有匹配項,則作為普通字符傳遞給命令。
Shell 中的通配符列表
通配符 | 描述 | 示例 |
---|---|---|
* | 匹配任意長度的字符(包括 0 個) | ls *.txt :匹配所有?.txt ?文件 |
? | 匹配單個任意字符 | ls file?.txt :匹配?file1.txt 、fileA.txt ?等 |
[charset] | 匹配字符集中的任意單個字符 | ls [abc].txt :匹配?a.txt 、b.txt 、c.txt |
[^charset] | 匹配不在字符集中的任意單個字符 | ls [^0-9].txt :匹配非數字開頭的?.txt ?文件 |
[a-z] | 匹配指定范圍內的單個字符(小寫字母) | ls [a-c]file :匹配?afile 、bfile 、cfile |
[[:class:]] | 匹配 POSIX 字符類中的字符 | ls [[:digit:]]* :匹配數字開頭的文件 |
POSIX 字符類(需用?[[:class:]]
?表示):
水平空白字符([:blank:]
)
定義:僅包含在同一行內起分隔作用的空白字符。
包含字符:
- 空格():ASCII 32(十進制),用于單詞分隔。
- 制表符(
\t
):ASCII 9,用于文本對齊(水平跳格)
垂直空白字符([:space:])
定義:用于換行或分頁的空白字符,會導致文本顯示位置移動到新行或新頁。
包含字符:
- 換行符(
\n
):ASCII 10,用于換行(如 Unix/Linux 系統的行尾符)。 - 回車符(
\r
):ASCII 13,用于回到行首(如 Windows 系統的行尾符為?\r\n
)。 - 換頁符(
\f
):ASCII 12,用于分頁(如打印時換頁)。 - 垂直制表符(
\v
):ASCII 11,用于垂直跳格(很少使用)。
字符類 | 描述 | 等價寫法 |
---|---|---|
[:alnum:] | 字母或數字 | [A-Za-z0-9] |
[:alpha:] | 字母(大小寫) | [A-Za-z] |
[:digit:] | 數字 | [0-9] |
[:lower:] | 小寫字母 | [a-z] |
[:upper:] | 大寫字母 | [A-Z] |
[:space:] | 空白字符(空格、制表符、換行符等) | — |
[:punct:] | 標點符號 | — |
通配符實例文件自己chuang
-
匹配以?
menu0
?開頭的文件ls menu0* # 輸出:menu01.sh menu02.sh menu03.sh menu04.sh
-
匹配以?
m
?開頭且后接單個字符的文件ls m? # 輸出:m1 m2 m3(假設存在這些文件)
-
匹配以?
m
?或?n
?開頭的文件ls [mn]* # 匹配 `m*` 和 `n*` 的文件
-
匹配字母開頭的文件(不區分大小寫)
ls [a-Z]* # 注意:`[a-Z]` 實際包含 ASCII 字符范圍,可能包含非字母(如 `[`、`\` 等),推薦用 `[[:alpha:]]` ls [[:alpha:]]* # 正確匹配所有字母開頭的文件
-
匹配數字開頭的文件
ls [[:digit:]]* # 等價于 `ls [0-9]*`
-
匹配字母或數字開頭的文件
ls [[:alnum:]]* # 匹配 `[0-9A-Za-z]*`
正則表達式(Regular Expression, RE)
正則表達式是用于文本內容匹配的模式,常用于?grep
、sed
、awk
?等工具中,針對文件內容而非文件名。
正則表達式基礎概念
- 作用:通過特殊字符組合,實現字符串的搜索、替換、刪除等操作。
- 優勢:簡化文本處理邏輯,減少代碼量。
- 分類:
- 基本正則表達式(BRE):支持基礎元字符,需轉義部分符號(如?
{}
)。 - 擴展正則表達式(ERE):支持更多元字符(如?
+
、?
),無需轉義?{}
?等符號。
- 基本正則表達式(BRE):支持基礎元字符,需轉義部分符號(如?
基本正則表達式(BRE)元字符
元字符 | 描述 | 示例 |
---|---|---|
^ | 匹配行首 | grep ^root /etc/passwd :匹配以?root ?開頭的行 |
$ | 匹配行尾 | grep bash$ /etc/passwd :匹配以?bash ?結尾的行 |
. | 匹配單個任意字符 | grep r.t /etc/passwd :匹配?r ?和?t ?之間有一個字符的行(如?rot 、rxt ) |
* | 匹配前一個字符 0 次或多次 | grep r.*t /etc/passwd :匹配?r ?和?t ?之間有任意字符的行 |
[] | 匹配字符集中的任意單個字符 | grep r[a-z]t /etc/passwd :匹配?r ?和?t ?之間為小寫字母的行 |
[^] | 匹配不在字符集中的任意單個字符 | grep r[^a-z]t /etc/passwd :匹配?r ?和?t ?之間為非小寫字母的行 |
\{n,m\} | 匹配前一個字符?n ?到?m ?次(需轉義) | grep 'r\{3\}t' /etc/passwd :匹配?r ?重復 3 次后接?t ?的行 |
POSIX 字符類(在正則中同樣適用):
grep [[:digit:]]\{3,4\} /etc/passwd # 匹配 3-4 位數字
擴展正則表達式(ERE)元字符
需通過?egrep
?或?grep -E
?使用,無需轉義特殊符號。
元字符 | 描述 | 示例與匹配結果 |
---|---|---|
+ | 匹配前一個字符?1 次或多次(至少出現 1 次)。 | egrep 'r+t' /etc/passwd 匹配? rt 、rrt 、rrrt ?等(r ?至少出現 1 次后接?t )。 |
? | 匹配前一個字符?0 次或 1 次(可選出現)。 | egrep 'colou?r' /etc/passwd 匹配? color ?或?colour (u ?可選:u可出現0次或者1次)。 |
{n} | 匹配前一個字符?恰好 n 次。 | egrep 'r{3}t' /etc/passwd 匹配? rrrt (r ?連續出現 3 次)。 |
{n,} | 匹配前一個字符?至少 n 次。 | egrep 'r{2,}t' /etc/passwd 匹配? rrt 、rrrt 、rrrrrt ?等(r ?至少出現 2 次)。 |
{n,m} | 匹配前一個字符?n 到 m 次之間(包含 n 和 m)。 | egrep 'r{2,4}t' /etc/passwd 匹配? rrt 、rrrt 、rrrrt (r ?出現 2-4 次)。 |
(pattern1|pattern2) | 匹配多個模式中的?任意一個(使用豎線?| ?分隔)。 | egrep '^(root|admin)' /etc/passwd 匹配以? root ?或?admin ?開頭的行。 |
正則表達式工具對比
工具 | 正則類型 | 說明 |
---|---|---|
grep | 基本正則表達式(BRE) | 需轉義?{} ?等符號 |
egrep | 擴展正則表達式(ERE) | 直接使用?+ 、? 、{} ?等符號 |
fgrep | 不支持正則 | 按字面匹配字符串 |
?正則表達式實例
-
匹配以?
bash
?結尾的行grep bash$ /etc/passwd # 基本正則 egrep bash$ /etc/passwd # 擴展正則(等價)
-
匹配 3-4 位數字
grep '[[:digit:]]\{3,4\}' /etc/passwd # BRE,需轉義 {} egrep '[[:digit:]]{3,4}' /etc/passwd # ERE,無需轉義
-
匹配以空白字符開頭、非空白字符后跟的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg # BRE,`\+` 表示 `+` egrep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg # ERE,直接用 `+`
-
匹配包含?
Failed
?或?FAILED
?的行(不區分大小寫)grep -i 'failed' /var/log/secure # 基本正則,`-i` 忽略大小寫 egrep -i 'failed|FAILED' /var/log/secure # 擴展正則,匹配任意模式
通配符與正則表達式對比
特性 | 通配符 | 正則表達式 |
---|---|---|
處理者 | Shell(路徑擴展) | 命令(如?grep ) |
作用對象 | 文件名或路徑 | 文本內容 |
元字符差異 | * 、? 、[] | .* 、+ 、() ?等 |
典型場景 | ls *.txt 、rm data_* | grep "pattern" file 、sed -e "s/regex/replace/" |
7.4 練習與答案(擴展)
練習 1:顯示?/etc/passwd
?中以不區分大小的?h
?開頭的行
grep -i ^h /etc/passwd # `-i` 忽略大小寫,`^h` 匹配行首
練習 2:顯示?/etc/passwd
?中以?sh
?結尾的行
grep sh$ /etc/passwd # `$` 匹配行尾
練習 3:顯示?/etc/fstab
?中以?#
?開頭、后跟一個或多個空白字符和非空白字符的行
grep "^#[[:space:]]\+[^[:space:]]" /etc/fstab # BRE,`\+` 表示一個或多個空白字符
egrep "^#[[:space:]]+[^[:space:]]" /etc/fstab # ERE,直接用 `+`
練習 4:查找?/etc/rc.d/rc.local
?中包含以?to
?開始并以?to
?結尾的字串的行
grep "to.*to" /etc/rc.d/rc.local # `.*` 匹配任意字符
練習 5:查找?/etc/passwd
中包含sbin行,或者以s開頭,以n結尾的單詞的行
1、grep -w 'sbin' /etc/passwd # `\<` 和 `\>` 表示單詞邊界-w 會強制 grep 僅匹配獨立的完整單詞,而非單詞的一部分。具體規則:
單詞邊界:單詞必須被非單詞字符(如空格、標點符號、換行符)包圍。
單詞字符:通常指字母、數字和下劃線(即 [A-Za-z0-9_])。選項 / 元字符 功能 示例匹配
-w 匹配完整單詞,自動添加單詞邊界檢查 grep -w 'foo' → 匹配 foo,但不匹配 foobar
\< 和 \> 正則表達式中的單詞邊界元字符 grep '\<foo\>' → 同上,但需手動添加元字符2、grep -Eo '\bs[a-z]*n\b' /etc/passwd # 僅匹配小寫字母
-o 是只顯示匹配內容
\b:顯式定義單詞邊界grep -Ew 's[a-z]*n' /etc/passwd注意:如果你要匹配以s開頭,以n結尾單詞的行,根據grep版本的問題,.*進行貪婪匹配,會盡可能多的去匹配,達不到預期的效果,所以我們把任意字符改為任意數量的小寫字母。
練習 6:查找?ifconfig
?結果中 1-255 之間的整數
ifconfig | egrep -w "[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]"
練習 7:顯示?/var/log/secure
?中包含?Failed
?或?FAILED
?的行
grep -i 'failed' /var/log/secure # 簡化寫法,匹配大小寫
練習 8:在?/etc/passwd
?中取出默認 Shell 為?bash
?的行
grep '/bin/bash$' /etc/passwd # 匹配行尾的 `/bin/bash`
練習 9:以長格式列出?/etc/
?下以?ns
?開頭、.conf
?結尾的文件
ls -l /etc/ns*.conf # 通配符直接用于文件名匹配
練習 10:高亮顯示?passwd
?文件中用戶名和加密密碼
grep -o '^[^:]*:[^:]*' /etc/passwd # 匹配冒號分隔的字段相當于匹配用戶名和加密密碼
總結
- 通配符:專注于文件名匹配,由 Shell 處理,語法簡單(如?
*
、?
)。 - 正則表達式:用于文本內容匹配,支持復雜模式(如?
^
、$
、.*
),需結合工具(grep
、egrep
)使用。 - 關鍵區別:作用對象不同(文件名 vs. 文本內容),元字符語法有差異。