ls [13] 和 ls {1,3} 有什麼不同?

ls [13] 和 ls {1,3} 有什麼不同?

我使用命令在目錄中創建了三個檔案touch inv{1..3}.txt。現在我使用了兩個命令,它們的輸出幾乎相同。這兩個命令是ls inv[13].txtls {1,3}.txt

那麼這兩者有何不同呢?方括號與大括號有何不同?我也在谷歌上搜尋“linux [..]”,但找不到任何東西,所以我可以知道這些東西在Linux術語中被稱為什麼嗎?

謝謝

答案1

  • {}稱為大括號擴充。它有兩種形式:{x..y}{x,y},將x和替換y為任何字母或數字值。

    在第一種形式中,{x..y}將擴展到從x到 的所有值y(包含在內)。例如,{2..5}將擴展為2, 3, 4, 5

    在第二種顯式形式中,{x,y}將只擴展為x, y。例如,{2,5}將擴展為25

    如果無法擴展,則按字面處理模式,例如 in {a..3}

    需要注意的重要一點是,在文件建立/匹配時,無論任何文件匹配如何,都會完成大括號擴展(如果可能)。

  • []稱為路徑名擴展(或通配)模式。與大括號擴充不同,您只能在符合檔案名稱時使用它,如果您在建立檔案時使用它,它將按字面意思處理。

    它有兩種形式:[xyz...][x-y]

    在第一種形式中,它將分別匹配方括號內的任何單個字符,即每個字符被單獨處理。因此, for它將匹配當前目錄中名為或 的[25].txt文件,而 for它將匹配任何名為或的文件。2.txt5.txt[245].txt2.txt4.txt5.txt

    在第二種形式中,在單獨匹配之前首先進行範圍擴展,如果可能的話,否則按字面意思處理。因此,對於[2-5]. txt,它將匹配任何名為2.txtor3.txt4.txtor 的檔案5.txt。如果範圍無法擴展,則會按字面處理,例如在 的情況下[a-3].txt


這兩者之間的一個重要的行為差異是當有更多的模式需要匹配而實際上匹配的模式更少時。由於無論如何都會完成大括號擴展,它會顯示某些檔案不存在的錯誤,而路徑名擴展將匹配任何可能的內容,而其余文件不會出現任何錯誤:

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

便攜性注意事項:

路徑[]名擴充運算子由 POSIX 定義,因此可在 Bourne shell 和衍生產品之間移植。

大括號擴展{}不是由 POSIX 定義的,因此不能在所有 shell 之間移植。例如, dashsh在Ubuntu中)沒有這個。它是從某些 shell 借用的csh,並且只能在某些 shell 上運行,例如bash, zsh, ksh93, fish。在實作之前,請確保您使用的 shell 支援此功能。


例子:

$ touch {1..3}.txt

$ ls {1..3}.txt
1.txt  2.txt  3.txt

$ ls {1,2,3}.txt
1.txt  2.txt  3.txt

$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt  2.txt  3.txt

$ ls {a..3}.txt
ls: cannot access {a..3}.txt: No such file or directory

$ ls [123].txt
1.txt  2.txt  3.txt

$ ls [1-3].txt
1.txt  2.txt  3.txt

$ ls [1-4].txt
1.txt  2.txt  3.txt

$ ls [a-3].txt
ls: cannot access [a-3].txt: No such file or directory

答案2

兩種形式之間的主要區別如下所示:

$ ls inv[15].txt
inv1.txt
$ ls inv{1,5}.txt
ls: cannot access 'inv5.txt': No such file or directory
inv1.txt

inv[15].txt是一個 glob,將擴展檔案系統上匹配檔案的清單。這是路徑名擴充

inv{1,5}.txt擴展為inv1.txt並且inv5.txt無論檔案系統上實際有哪些檔案。這是大括號擴展

相關內容