Bash
使用帶有 glob *.{a,b,}test 的大括號擴展時,忽略 zsh 中的“不匹配”
我想列出一個名為的文件夾
foldername
中具有副檔名的所有文件test
,atest
或btest
。我的第一想法是跑
ls ./foldername/*.{a,b,}test
這可以正常工作,除非副檔名沒有任何內容
atest
,在這種情況下我會收到錯誤消息zsh: no matches found: ./foldername/*.atest
。有什麼方法可以簡單地忽略此錯誤並列印確實存在的文件?
我需要這個在 zsh 和 Bash 中工作。
最好這樣做
find
:find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
在
ls -d ./foldername/*.{a,b,}test
{a,b,...}
不是 glob 運算符,這是大括號擴展,首先擴展為:ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test
並且每個 glob 單獨擴展,如果任何 glob 不匹配,則命令將按照您的預期取消
zsh
(或fish
; 在 中bash
,您需要failglob
獲得類似行為的選項)。在這裡,您希望使用與所有這些文件匹配的單個 glob,並且僅在該 glob 不匹配任何文件時才取消命令:
ls -d ./foldername/*.(a|b|)test
您不想使用
nullglob
,就好像沒有匹配的 glob 一樣,它會在ls
沒有參數的情況下執行,所以列出目前目錄。cshnullglob
在這方面更好,因為它會刪除不匹配的 glob,但如果所有 glob 都不匹配,仍會取消該命令。您不想使用
nonomatch
,因為這會給您bash
帶來可恥的破壞行為。對於同時適用於
zsh
and的 glob 替代方案bash
,您可以使用 ksh glob(set -o kshglob
inzsh
和shopt -s extglob
inbash
)。然後,你會這樣做:
ls -d ./foldername/*.@(a|b|)test
或者:
ls -d ./foldername/*.?([ab])test
添加
failglob
選項bash
以避免當 globls
不匹配時直接傳遞給它。請參閱為什麼 nullglob 不是預設值?了解更多資訊。