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}将扩展为2345

    在第二种显式形式中,{x,y}将被扩展为仅xy。例如,{2,5}将被扩展为25

    如果无法扩展,则按字面意思处理该模式,例如{a..3}

    需要注意的重要一点是,在文件创建/匹配时,无论文件是否匹配,都会进行括号扩展(如果可能)。

  • []被称为路径名扩展(或通配符)模式。与括号扩展不同,您只能在匹配文件名时使用它,如果您在创建文件时使用它,它将被按字面处理。

    它有两种形式:[xyz...][x-y]

    在第一种形式中,它将分别匹配方括号内的任意单个字符,即每个字符都单独处理。因此,对于 ,[25].txt它将匹配当前目录中名为2.txt或 的文件5.txt,而对于 ,[245].txt它将匹配任何名为2.txt4.txt或 的文件5.txt

    在第二种形式中,首先进行范围扩展,然后进行逐个匹配,如果可能,则按字面处理,否则按字面处理。因此对于[2-5]. txt,它将匹配名为2.txt3.txt4.txt或 的任何文件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 之间移植。例如, Ubuntu 中的dash( sh) 没有这个。它是从某些 shell 借用的csh,并且只能在某些 shell 上使用,例如bash,,,zshksh93fish实现之前,请确保您使用的 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不管文件系统上实际有哪些文件。这是括号扩展

相关内容