為什麼在 Shell (Bash) 中應該首選“字元類”而不是“字元範圍”?
Linux 命令行(書 - 頁數 47)說:
…你必須非常小心他們
$$ character ranges $$因為除非配置正確,否則它們不會產生預期的結果。現在,您應該避免使用它們並改用字元類。
這本書沒有給出任何理由,除此之外。
**問題 - 1:**那麼,為什麼字元類(例如
[:alnum:]
,[:alpha:]
,[:digit:]
等)應該優於字元範圍(例如[a-z]
,[A-Z]
,[0-9]
等)?問題 - 2:是否也
[:alpha:]
代表其他語言的[a-z]
,[A-Z]
和大小寫字母?同樣,是否也[:digit:]
包括其他語言的數字?如果他們匹配,那就是。(我知道兩個問題,但在這種情況下,它們幾乎是相互關聯的,IMO。)
根據手冊
bash
頁,LC_COLLATE
環境變數會影響字元範圍,完全按照 Hauke Laging 的回答:LC_COLLATE 此變數確定在對路徑名擴展的結果進行排序時使用的排序順序,並確定範圍表達式、等價類和路徑名擴展和模式匹配中排序序列的行為。
另一方面,
LC_CTYPE
影響字元類:LC_CTYPE此變數確定字元的解釋以及路徑名擴展和模式匹配中字元類的行為。
這意味著如果您在英語、從左到右、拉丁字母、阿拉伯數字的上下文中思考,這兩種情況都可能存在問題。
如果您真的很合適,並且/或者正在為多語言環境編寫腳本,那麼最好確保您在匹配文件時知道您的語言環境變數是什麼,或者確保您正在編碼完全通用的方式。
但是,除非您學習過語言學,否則很難預見某些情況。
但是,我不知道使用拉丁語的語言環境會改變字母順序,所以
$$ a-z $$會工作。拉丁字母表有*一些擴展,它們以不同的方式整理連字和變音符號。*但是,這裡有一個小實驗:
mkdir /tmp/test cd /tmp/test export LC_CTYPE=de_DE.UTF-8 export LC_COLLATE=de_DE.UTF-8 touch Grüßen ls G* # This says ‘Grüßen’ ls *[a-z]en # This says nothing! ls *[a-zß]en # This says ‘Grüßen’ ls Gr[a-z]*en # This says nothing!
這很有趣:至少對於德語來說,像 ü 這樣的變音符號和像 ß 這樣的連字都不會被折疊成拉丁字元。(要麼那個,要麼我搞砸了語言環境的變化!)
當然,這可能對您不利,如果您要查找以字母開頭的文件名,
[a-z]*
請將其應用於以“Ä”開頭的文件。