我想使用 .jpg 列出所有子目錄中的所有 .jpg 檔案ls。
對于同一目錄,這可以正常作業:
ls *.jpg
但是,當使用-Rfor 遞回時:
ls -R *.jpg
我得到:
zsh:no matches found: *.jpg
為什么這不起作用?
注意:我知道可以使用findorgrep但我想知道為什么上述方法不起作用。
uj5u.com熱心網友回復:
該程式ls并非旨在自行處理模式。
運行ls -R *.jpg時,模式*.jpg不會直接傳遞給ls. shell 將其替換為與該模式匹配的所有檔案的串列。(僅當沒有具有匹配名稱的檔案時,ls才會看到檔案名*.jpg并且找不到該名稱的檔案。)由于您使用zsh的是(使用默認設定setopt nomatch),它會列印一條錯誤訊息,而不是將模式傳遞給ls.
如果有匹配的檔案,例如A.jpg, B.jpg, C.jpg, 命令
ls *.jpg
將由 shell 運行為
ls A.jpg B.jpg C.jpg
與此相反,find它的設計目的是處理模式與它的-name測驗。使用時,find您應該確保模式沒有 被 shell 替換,例如使用-name '*.jpg'or -name \*.jpg。否則,如果當前目錄中有匹配的檔案,您可能會得到意外結果或錯誤。
編輯:
如Martin Tournoij 的回答所示,您可以使用遞回 glob 模式ls **/*.jpg,但這也由 shell 處理,而不是 by ls,因此您不需要 option -R。默認情況下啟用此遞回模式,您zsh需要使用.**bashshopt -s globstar
uj5u.com熱心網友回復:
shell 首先展開所有 glob 模式,然后運行命令。因此,從ls的角度來看,ls *.jpg與您鍵入ls one.jpg two.jpg. 僅當您在目錄上使用它時,該-R標志ls才有意義,而您在這里沒有這樣做。
這也是為什么mv *.jpg *.png在 Unix 系統上不能按預期作業的原因,因為mv從來沒有看到這些模式,而只是看到它擴展到的檔案名(它在例如 Windows 上,其中 globbing 是由程式而不是 shell 完成的;有優點和兩種方法的缺點)。
*匹配除a之外的所有字符/,因此*.jpg僅擴展為當前目錄中的模式。**/是相似的,但也匹配/,所以它擴展到任何目錄中的模式。bash 和 zsh 都支持這一點。
所以ls **/*.jpg會做你想做的;你不需要使用findor grep。在 zsh 中,尤其是您很少需要使用,find因為 globbing 比在標準 Bourne shell 或 bash 中強大得多。
在 zsh 中,您也可以使用setopt glob_star_shortthen**.jpg也可以,這是**/*.jpg.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/512506.html
