這篇文章將要介紹方括號及其在命令列中的不同用法。
看完花括號在命令列中的用法[1]之後,現在我們繼續來看方括號([]
)在背景關係中是如何發揮作用的。
通配
方括號最簡單的用法就是通配。你可能在知道“”這個概念之前就已經透過通配來匹配內容了,列出具有相同特徵的多個檔案就是一個很常見的場景,例如列出所有 JPEG 檔案:
-
ls *.jpg
使用萬用字元來得到符合某個樣式的所有內容,這個過程就叫通配。
在上面的例子當中,星號(*
)就代表“0 個或多個字元”。除此以外,還有代表“有且僅有一個字元”的問號(?
)。因此
-
ls d*k*
可以列出 darkly
和 ducky
,而且 dark
和 duck
也是可以被列出的,因為 *
可以匹配 0 個字元。而
-
ls d*k?
則只能列出 ducky
,不會列出 darkly
、dark
和 duck
。
方括號也可以用於通配。為了便於演示,可以建立一個用於測試的目錄,併在這個目錄下建立檔案:
-
touch file0{0..9}{0..9}
(如果你還不清楚上面這個命令的原理,可以看一下另一篇介紹花括號的文章[1])
執行上面這個命令之後,就會建立 file000
、file001
、……、file099
這 100 個檔案。
如果要列出這些檔案當中第二位數字是 7 或 8 的檔案,可以執行:
-
ls file0[78]?
如果要列出 file022
、file027
、file028
、file052
、file057
、file058
、file092
、file097
、file098
,可以執行:
-
ls file0[259][278]
當然,不僅僅是 ls,很多其它的命令列工具都可以使用方括號來進行通配操作。但在刪除檔案、移動檔案、複製檔案的過程中使用通配,你需要有一點橫向思維。
例如將 file010
到 file029
這 30 個檔案複製成 archive010
到 archive029
這 30 個副本,不可以這樣執行:
-
cp file0[12]? archive0[12]?
因為通配只能針對已有的檔案,而 archive
開頭的檔案並不存在,不能進行通配。
而這條命令
-
cp file0[12]? archive0[1..2][0..9]
也同樣不行,因為 cp 並不允許將多個檔案複製到多個檔案。在複製多個檔案的情況下,只能將多個檔案複製到一個指定的目錄下:
-
mkdir archive
-
cp file0[12]? archive
這條命令是可以正常執行的,但它只會把這 30 個檔案以同樣的名稱複製到 archive/
目錄下,而這並不是我們想要的效果。
如果你閱讀過我關於花括號的文章[1],你大概會記得可以使用 %
來截掉字串的末尾部分,而使用 #
則可以截掉字串的開頭部分。
例如:
-
myvar="Hello World"
-
echo Goodbye Cruel ${myvar#Hello}
就會輸出 Goodbye Cruel World
,因為 #Hello
將 myvar
變數中開頭的 Hello
去掉了。
在通配的過程中,也可以使用這一個技巧。
-
for i in file0[12]?;\
-
do\
-
cp $i archive${i#file};\
-
done
上面的第一行命令告訴 Bash 需要對所有 file01
開頭或者 file02
開頭,且後面只跟一個任意字元的檔案進行操作,第二行的 do
和第四行的 done
代表需要對這些檔案都執行這一塊中的命令。
第三行就是實際的複製操作了,這裡使用了兩次 $i
變數:第一次在 cp 命令中直接作為源檔案的檔案名使用,第二次則是截掉檔案名開頭的 file
部分,然後在開頭補上一個 archive
,也就是這樣:
-
"archive" + "file019" - "file" = "archive019"
最終整個 cp 命令展開為:
-
cp file019 archive019
最後,順帶說明一下反斜槓 \
的作用是將一條長命令拆分成多行,這樣可以方便閱讀。
在下一節,我們會瞭解方括號的更多用法,敬請關註。
朋友會在“發現-看一看”看到你“在看”的內容