`.[].foo[]` 在 bash 中做什么?为什么它匹配“..”?

`.[].foo[]` 在 bash 中做什么?为什么它匹配“..”?

请看以下内容:

$ echo .[].aliases[]
..
$ echo .[].foo[]
..
$ echo .[].[]
..
$ echo .[].xyz[]
..
$ echo .xyz[].xyz[]
.xyz[].xyz[]
$ echo .xyz[].[]
.xyz[].[]

显然这似乎是在传递一些东西,但我不明白结果是如何组合在一起的。根据我的理解,[]这是一个空的字符类。直观地说,如果

  • 它只匹配空字符串;在这种情况下,我希望 bash 能够完整地重现,因为该目录中没有任何内容与它匹配,但也匹配诸如..aliases(在第一个示例中)之类的内容,
  • 或者什么都没有;在这种情况下,我希望 bash 也能完全重现该字符串。

这是 GNU bash 版本 4.4.23(1)-release 的版本。

答案1

开始[一组。一组由 终止]。但有一种方法可以将]其作为集合的一部分,那就是将 指定]为第一个字符。由于空集没有任何意义,因此这并不含糊。

所以你的例子基本上都是一个点,后面跟着一个包含点的集合,因此它匹配两个点。

后面的示例未找到任何文件,因此会逐字返回。

答案2

仅有的字符串是不是受到通配符的影响:

$ echo ".[].aliases[]"
.[].aliases[]

但未加引号的字符串容易发生通配。包含*or ?(有效) (括号表达式)的不带引号的字符串[]将被与其匹配的文件列表修改。与 a*将转换为匹配目录中的所有文件以及 a?将仅匹配一个字符的文件一样,a(有效)[]将匹配包含括号内字符的文件。点是有效字符:

$ echo a[.]b
a[.]b

$ touch "a.b"
$ echo a[.]b
a.b

为了能够匹配 a,]它应该是括号内的第一个字符:

$ touch "a]b"
$ ls a[]]b
a]b

空括号表达式没有任何意义(并且不会扩展):

$ touch ab
$ ls a[]b
ls: cannot access 'a[]b': No such file or directory

这就是为什么它有效:

$ touch a]c abc afc azc a:c a?c aoc 
$ ls a[]bfz:?]c
abc  a:c  a?c  a]c  afc  azc

因为[想法是相似的:

$ touch a[c
$ ls a[[]c
a[c

但它可以位于括号表达式中的任何位置:

$ ls a[]bf[z:?]c
abc  a:c  a?c  a[c  a]c  afc  azc

$ ls a[]bfz:?[]c
abc  a:c  a?c  a[c  a]c  afc  azc

您发布的字符串.[].foo[]将匹配一个点,后跟 a ]、 a .、 a f、 ao或 a [。它类似于:

$ echo a[].foo[]c
a[c a]c afc aoc

它将匹配如下:

$ touch .] .f .o .[ .a .b .z

$ echo .[].foo[]
.. .[ .] .f .o

..请注意,不需要创建目录条目,因为默认情况下它存在于每个目录中。但简单的点.不会与全局匹配,因为它需要显式匹配(通过实际使用点)。

但这不会匹配,..aliases因为括号表达式只会匹配特点。要匹配多个字符,您需要使用*(任何内容):

$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo .[].aliases[]
.. .[ .] .a

$ echo .[].aliases[]*
.. .[ .] .a ..a ..ali ..alias ..aliases ..i ..l

相关内容