Brace-Expansion
a 和有什麼不一樣bcbCbcd
(括號)和a{b,c}d
(大括號)?
a[bc]d
和 和有什麼不一樣a{b,c}d
?為什麼人們a{b,c}d
在已經有的時候使用a[bc]d
?
兩者完全不同。
a[bc]d
是一個文件名模式(在 以外的 shell 中fish
)。它將擴展到兩個文件名abd
,acd
如果它們是目前目錄中現有文件的名稱。
- 該
[...]
部分是一個括號表達式,它匹配列出的字元中的單個字元(或在包括範圍時整理元素)。要匹配模式a[bc]d
,字元串之間a
和d
文件名中的字元必須是 ab
或 ac
。- 如果
abd
存在但acd
不存在,那麼它只會擴展為abd
,反之亦然。- 如果兩者都不存在
abd
,也不acd
存在,具體取決於 shell 和選項,它會觸發錯誤(原始 Unixsh
、(t)csh
、zsh
、fish
、bash -O failglob
)並可能退出 shell,或者保持模式未擴展¹(Bourne-like 和rc
-like shell)或擴展為什麼都沒有(bash/zsh/yash -o nullglob
、一些舊版本的fish
、原始 Unixsh
以及(t)csh
同一命令中是否有其他匹配的 glob)。
a{b,c}d
是一個大括號擴展(在支持這些的 shell 中)。它將擴展到兩個字元串abd
和acd
.
- 該
{...}
部分是一組以逗號分隔的字元串(在此範例中;在某些 shell 中,它也可能是一個範圍,例如a..k
或20..25
更高級的範圍,例如00..20..2
or0..20..2%02d
),並且通過將這些字元串中的每一個與側翼組合來計算擴展字元串a
和d
. 這些字元串可能比單個字元長,也可能是大括號擴展本身。- 無論這些字元串是否對應於現有文件名,都會發生擴展。
如果您正在構造字元串,請使用大括號擴展。如果要匹配文件名,請使用文件名模式。
¹在這種特殊情況下,
a[bc]d
可能恰好是現有文件的名稱,這就是為什麼rm -f ./*.[ch]
在這些 shell 中使用類似的東西可能很危險,而且rm -f ./*.{c,h}
問題不大。