這個(gè)題目說穿了, 就是要探討Wildcard與Regular Expression的差別的。 這也是很多初學(xué)shell的朋友很容易混淆的地方。
首先,讓我們回到十三問之第2問, 再一次將我們提到的command line format 溫習(xí)一次:
command_name options arguments
同時(shí),也再來理解一下,我在第5章所提到的變量替換的特性:
先替換,再重組 command line!
有了這個(gè)兩個(gè)基礎(chǔ)后,再讓我們來看Wildcard是什么回事吧。
首先,
`Wildcard` 也是屬于 `command line` 的處理工序,作用于 `arguments` 里的 `path` 之上。
沒錯(cuò),它不用在command_name,也不用在options上。
而且,若argument不是path的話,那也與wildcard無關(guān)。
換句更為精確的定義來講,
`wildcard`是一種命令行的路徑擴(kuò)展(path expansion)功能。
提到這個(gè)擴(kuò)展,那就不要忘了 command line的“重組”特性了!
是的,這與變量替換(variable subtitution)及
命令替換(command substitution)的重組特性是一樣的。
也就是在wildcard進(jìn)行擴(kuò)展后,
命令行會(huì)先完成重組,才會(huì)交給shell來處理。
了解了wildcard的擴(kuò)展與重組特性后,
接下來,讓我們了解一些常見的wildcard吧。
| wildcard | 功能 |
|---|---|
| * | 匹配0個(gè)或多個(gè)字符 |
| ? | 匹配任意單一字符 |
| [list] | 匹配list中任意單一字符 |
| [!list] | 匹配不在list中任意單一字符 |
| {string1,string2,...} | 匹配string1或者stsring2或者(...)中其一字符串 |
Note: list 中可以指定單個(gè)字符,如abcd, 也可以指定ASCII字符的起止范圍,如 a-d。 即[abcd] 與 [a-d] 是等價(jià)的,稱為一個(gè)自定義的字符類。
例如:
a*b # a 與 b 之間可以有任意個(gè)字符(0個(gè)或多個(gè)),如aabcb, axyzb, a012b,ab等。
a?b # a 與 b 之間只能有一個(gè)字符,但該字符可以任意字符,如 aab, abb, acb, azb等。
a[xyz]b # a 與 b 之間只能有一個(gè)字符,但這個(gè)字符只能是x或者y或者z,如:axb, ayb, azb這三個(gè)。
a[!0-9]b# a 與 b 之間只能有一個(gè)字符,但這個(gè)字符不能是阿拉伯?dāng)?shù)字,如aab,ayb,a-b等。
a{abc,xyz,123}b # a 與 b之間只能是abc或者xyz或者123這三個(gè)字串之一,擴(kuò)展后是aabcb,axyzb,a123b。
[! ] 中的! 只有放在第一位時(shí),才有取反的功效。
eg:
[!a]* 表示當(dāng)前目錄下不以a開頭的路徑名稱;
/tmp/[a\!]*表示/tmp目錄下所有以a 或者 ! 開頭的路徑名稱;
思考:為何!前面要加\呢?提示是十三問之4.
[ - ]中-左右兩邊均有字符時(shí),才表示一個(gè)范圍,否則,僅作-(減號(hào))字符來處理。
舉例:
/tmp/*[-z]/[a-zA-Z]* 表示/tmp 目錄下所有以z或者-結(jié)尾的子目錄中,
以英文字母(不分大小寫)開頭的目錄名稱。
*.txt并不能匹配.txt但能匹配1.txt這樣的路徑名。
但1*txt及1?txt均可匹配1.txt這樣的路徑名。基本上,要掌握wildcard并不難, 只要多加練習(xí),再勤于思考,就能靈活運(yùn)用了。
再次提醒:
別忘了wildcard的"擴(kuò)展" + "重組" 這個(gè)重要特性,而且只作用在 argument的path上。
比方說, 假如當(dāng)前目錄下有: a.txt b.txt c.txt 1.txt 2.txt 3.txt 這幾個(gè)文件。
當(dāng)我們?cè)诿钚兄袌?zhí)行ls -l [0-9].txt的命令行時(shí),
因?yàn)閣ildcard處于argument的位置上,
于是根據(jù)匹配的路徑,擴(kuò)展為: 1.txt 2.txt 3.txt,
在重組出ls -l 1.txt 2.txt 3.txt 這樣的命令行。
因此,你在命令行上敲 ls -l [0-9].txt
與 ls -l 1.txt 2.txt 3.txt 輸出的結(jié)果是一樣,
原因就是在于此。