ZSH Globbing 語法解釋
我想將所有內容
dotfiles
從我的~
文件夾複製到 git repo 以備份它們,我正在使用ZSH
.我遇到了這個似乎有效的命令:
cp -a ~/.[^.]* .
——最後的地方。是 git 目錄。我不明白這是如何工作的。任何人都可以給我一個指南,或者告訴我用Google了解更多資訊嗎?
我試過了
ZSH
+
[^]
+
globbing
該語法適用於除此之外的某些 shell
zsh
,甚至在那裡,它是錯誤的。
.[^.]*
匹配以 開頭的文件名,.
後跟除 之外的字元.
,後跟 0 個或多個字元。這是您在
.
包含...``.*
.
並且..
是用於分別引用目前目錄和父目錄的導航工具。它們在 glob 擴展中沒有位置,因為 glob 是生成實際文件列表的工具¹。儘管如此,從歷史上看,shell 一直將它們包括在它們的全域擴展中,因為它們被readdir()
.
zsh
,就像 Forsyth shell 及其後代(pdksh、mksh、OpenBSD sh…)或fish
shell 已經修復了這個問題,並且從不包含.
也不..
在文件名生成的結果中,即使在像這樣的 glob 中:$ echo (.|..) zsh: no matches found: (.|..)
在一般情況下它也是錯誤的,因為它錯過了像
..foobar
.另請注意
[^.]
,儘管許多 shell 都支持,但它不是標準的 POSIX 語法。在 POSIX
sh
語法中,您需要:cp -a ~/.[!.]* ~/..?* .
(我們在後面添加一個
..?*
或多個字元的匹配項,以涵蓋上述文件名的類型)。..``..foobar
在
zsh
(以及上面提到的其他外殼)中,您只需要:cp -a ~/.* .
希望最終會被 POSIX 允許/推薦用於 sh,我們將看到更多其他 shell 效仿。
¹ 在歷史記錄中,根據傳說,名稱以隱藏開頭的文件的概念
.
起源於70 年代實用程序的早期版本中的一個錯誤,該錯誤ls
最終導致所有以開頭的文件名.
都被隱藏,而意圖是只是為了隱藏.
和..
。當人們開始依賴它來隱藏文件時,該錯誤成為了一項功能