在
UNIX 系統中有時難免會用上長長的路徑,長長的檔案名稱或一大堆的檔名在指令中,所以在 C Shell
中提供了幾個符號來幫助我們解決這使用上的困擾。這就是檔名擴展的功能,也有人稱它為
wildcard。相信你對“*”這個符號一定不會陌生才對。你一定常運用它來代表所有相關的檔案名稱,它便是包含在這個檔名擴展的功能之一。以下讓我們
通盤地看一看整個的檔名擴展功能。
3-3-1 符號“*”與“?”
一般使用者使用符號“*”的比例可能遠多過使用符號“?”。這可能是因為符號“*”代表任何的字元(包含
null)。而符號“?”僅用以代表任何一個單一的字元。這差別是相當大的。讓我們來看一個例子:
1 % ls
a a1 a2 aa aaa
2 % ls a*
a a1 a2 aa aaa
第一個指令 ls 告訴我們共有五個檔案,當我們以“a*”來顯示相關檔案時,五個檔案全出現了,其中檔案a的出現證明了符號“*”連
null 都代表的特性。而檔案 aaa 的出現告訴了我們一個符號“*”便可代表多個字元。接下來我們把符號“*”換成符號“?”來看看結果的差異性。
3 % ls a?
a1 a2 aa
你可發現檔案 a 沒出現,因為符號“?”不代表 null;檔案 aaa 也沒出現,這是因為符號“?”僅代表一個字元。如果你必需用
a?? 才行,如下:
4 % ls a??
aaa
看清楚僅有檔案 aaa 出現而已,a1、a2、aa 等只有兩個字元不符合條件。所以說使用者為了在使用上的方便,會運用符號“*”多過符號“?”大概就是這個原因吧!但有一點必須說明當你在撰寫
shell 程式時,如果需要使用類似的功能時,別忘了符號“?”是比較嚴謹的安全的作法,不妨改便你的使用習慣看看。因為撰寫 shell
程式要應付的情況較多,嚴謹一點的作法比較不會產生 bug。
對於“*”這個符號,真可說是懶人之“星”。像指令 cd 到某目錄時,目錄名稱打到一半接著“*”代表之。ls、vi、lpr、cp、rm
等等等的指令也均如法泡製。
在符號“*”的運用上也不盡然是所有指令都能接受的,像指令 mv、cp 便會有語法上無法接受“*”代表檔案的情況,看下面:
% mv acct.* acctold.*
usage: mv [-if] f1 f2 or mv [-if] f1 ... fn d1 (`fn' is a file
or directory)
% cp acct.* acctold.*
Usage: cp [-ip] f1 f2; or: cp [-ipr] f1 ... fn d2
哈哈!太懶了!!被電腦“教訓”了一頓!!!不過說實在的作者我一直認為懶惰是人類發明創造的原動力!一切的偉大發明皆來自於偉大的懶惰。指令不能滿足我們的懶惰,則我們自己便應該為自己創造出一個屬於自己的“懶惰功能”來。在
Shell 程式設計單元中你將可為自己的懶惰感到無比的光榮。
3-3-2 符號“[...]”
這個符號的功能在為你定義字元、數字的範圍;它可以代表一個範圍內的一群數字或者是字母,也可代表很多個獨立的字元,或者是數字。在使用上相當具有彈性。要使用該符號“[...]”代表一個範圍時,範圍必須由小到大,兩者之間以符號“-”連接。
[0-9] 代表0、1、2、3、4、5、6、7、8、9等數字
[a-z] 代表字母a、b、c、d、...、x、y、z
[A-Za-z] 代表大寫字母A到Z或小寫字母a到z,既大小寫字母全部。
[A-z] 同上
[9-4] 範圍錯誤(錯誤示範)
[z-a] 範圍錯誤(錯誤示範)
要代表多個單獨的字元,只要一個個字元加入括號中便可。如下所示:
[abs] 代表 a 或 b 或 s
[1235] 代表 1 或 2 或 3 或 5
[ab][12] 代表 a1 或 a2 或 b1 或 b2
再提醒你一次,範圍只能由小到大,不可由大到小。如果用由大到小的方式雖然不會產生錯誤訊息,但結果一定是錯誤的。這一點自己可上機試試!以下我們來看一些實際運用的例子:
想一次顯示兩種尾號不同的所有檔案時,如下例所示:
% ls *.[sc]
backup1.c backup3.s backup2.c backup4.s
想將某個範圍的資料檔案彙整成一個新檔案,比方如上面這四個檔案合起來建一個新檔案。用法如下:
% cat backup[1-4].[sc] > backup.new
又譬如要將 aa1、aa2、aa3 三個目錄下的檔案拷貝到另一個目錄 all 之下,也可以使用得上。如下例:
% cp aa[1-3]/* ~/all/.
但是這個符號如果運用到 mkdir 指令時會產生錯誤的,這點請注意。比方你想一次新建五個目錄
disk1、disk2、disk3、disk4、disk5。假定你使用以下的方式:
% mkdir disk[1-5]
No match.
錯誤訊息告訴你“No match.”,錯在那裡呢?事實上,在使用的語法來說並沒有錯。只不過是
mkdir 指令無法接受這種用法,所以造成指令無法執行成功,產生了錯亂的訊息輸出。雖是如此,但這個法則的可組合運用還是相當好用的。請愛用善用之。
3-3-3 符號“{,,,}”
在前一個符號的最後指令 mkdir 的例子中,該符號做不到的,這個符號“{,,,}”可幫你做到。語法如下:
% mkdir disk{1,2,3,4,5}
就這樣一次新建五個目錄 disk1、disk2、disk3、disk4、disk5。或者是像以下的運用:
% mkdir man/{cat,man}{1,2,3,4,5,6,7,8}
一道 mkdir 指令一次建立 16 個目錄。簡單好用的很。
有
時它的功能會讓人覺得蠻接進符號“[...]”的,但它們所適合處理的情況其實並不太相同。符號“[...]”所適合處理的是比較簡單化的字元,較複雜無
規則性的字元則使用符號“{,,,}”比較恰當。假如我們要將三個存放在 /usr/include 目錄下的檔案一起拷貝到到 ~/time
目錄下,檔案名稱分別為
time.h、stdlib.h、termio.h,這如果要運用前面符號“[...]”來“簡化”指令,根本是不可能的事。但是,我們可以運用符號
“{,,,}”來處理,請看下例:
% cp /usr/include/{time,stdlib,termio}.h
~/time
這就是符號“{,,,}”所適用的強處。不過符號“{,,,}”對於 “範圍” 的處理能力並不能像符號“[...]”那樣強,可以使用到符號“-”來做到像這樣“[0-9]”簡潔地代表
0 到 9 的“範圍”功能,這點倒叫人在使用上感到有些遺憾。以下讓我們來看看幾個運用符號“{,,,}”來 精簡化指令的實際例子:
% mkdir disk1-1 disk1-2 disk1-3 disk2
% mkdir disk{1{-1,-2,-3},2}
% mv disk2 disk3
% mv disk{2,3}
% diff echo2.c echo2.c.org
% diff echo2.c{,org}
3-3-4 符號“~”
符號“~”代表的是使用者自己的 home 目錄。它有一個比較特殊的用法,就是在符號“~”之後如果接上另一個使用者名稱,則便代表該使用者的
home 目錄。這點在路徑名稱的運用上幫助相當大。比方你要到另一個使用者 yeats 的 home 目錄下,你可以毫不考慮目前的工作目錄,及你是否知到該使用者的
home 目錄,馬上使用這個用法在 cd 指令上,便可改變工作目錄到該使用者的 home 目錄之下。如下所示:
% pwd
/user1/akira/project
% cd ~yeats
% pwd
/user2/group1/yeats
像此類的運用最適合同一個工作團體,使用者與使用者之間的檔案傳輸,如下示:
% cp backup.c ~yeats
% cp backup.c /user2/group1/yeats
以上這兩個指令做的是同一件事情,你會喜歡下那一個呢?尤其當你會搞不清楚那一個使用者的目錄在那裡時,你將會格外的喜歡上它。