双星号 (**) 通配符是啥意思?

Posted

技术标签:

【中文标题】双星号 (**) 通配符是啥意思?【英文标题】:What do double-asterisk (**) wildcards mean?双星号 (**) 通配符是什么意思? 【发布时间】:2015-03-26 10:16:57 【问题描述】:

我尝试了以下命令,但无法解释结果:

ls **

我不确定它到底输出了什么以及为什么。

【问题讨论】:

【参考方案1】:

您很可能会看到一些 shell 的特殊功能,它允许通配符文件名模式跨目录边界匹配,而不是单个 *,后者是仅在目录内匹配的通配符。

如果您没有这样的 shell,** 可能会等同于 *,因为“匹配零个或多个字符后跟零个或多个字符”与仅“匹配零个或多个字符”相同.

但如果你有这样的 shell,** 将匹配当前目录中的所有文件和目录和子目录,而* 只匹配当前目录中的文件和目录。 (在这两种情况下,名称以. 开头的“点文件”都不匹配)。

** 的真正威力来自于您在更具体的模式中使用它。例如,**/*.txt 可以指定所有.txt 文件,无论它们位于哪个子目录中,而*.txt 仅匹配当前目录中的文件。

您应该查看您的 shell 的通配符匹配规则,以确定您的 shell 正在做什么。例如,bash manual 表示:

* 匹配任何字符串,包括空字符串。当。。。的时候 'globstar' shell 选项已启用,并且在文件名中使用了 '*' 扩展上下文,两个相邻的 '*' 用作单个模式将 匹配所有文件和零个或多个目录和子目录。 如果后跟一个 '/',两个相邻的 '*' 将只匹配 目录和子目录。

bash 的最新版本中,'globstar' shell 选项默认被禁用。通过以下方式启用:

shopt -s globstar

我相信 zsh 也支持这种语法。

请务必记住,通配符是由 shell 扩展的,而不是由 ls 命令扩展的。如果您键入ls **ls *.txtls 命令本身永远不会看到* 字符;它只会看到与模式匹配的扩展文件列表,就像您在命令行上键入了整个列表一样。

【讨论】:

它比“匹配当前目录和子目录中的所有文件和目录”或 bash 手册中所说的稍有细微差别,但只有一点点。请参阅***.com/a/66744400/8910547底部的表格和我对`**.md`和**f.md的评论 我编辑了解释,理顺了流程,添加了一个例子,并取消了对“递归”的引用,这意味着不同的东西......(正如 Inigo Montoya 所说,“你一直在使用那个词. 我不认为这意味着你认为它意味着什么。”?)【参考方案2】:

其他答案已很好地涵盖了此特定通配符的确切行为,但有关一般情况的信息可能有用。

这种行为不限于ls,被称为“globbing”,它是基于与现有文件名匹配的模式扩展。需要注意的是,这些模式不使用正则表达式语法。

shell 在将参数发送到程序之前对其进行预处理。通常有多个级别的扩展,其中一些涉及通配。

有关文件 glob 模式中可用的其他通配符的更多信息的一个很好的资源是 unix 联机帮助页。可以找到 glob 的在线版本here。

最后,这是一个简单的例子,说明它可以为您做什么,尤其是与其他 shell 扩展好东西结合使用时,在这种情况下是由 bash shell 提供的。有关此示例中使用的扩展的信息可以在 Bash Guide for Beginners 中找到 - 这是我的 goto 资源,尽管有标题。

ls *01..04.txt,csv 变为 ls *01.txt *01.csv *02.txt *02.csv *03.txt *03.csv *04.txt *04.csv

可以输出如下内容:

input_01.txt input_02.txt input_03.txt input_04.txt output_01.csv output_02.csv output_03.csv output_04.csv

跳过这些:

input_05.txt input_06.txt input_07.txt input_08.txt input_09.txt input_10.txt output_05.csv output_06.csv output_07.csv output_08.csv output_09.csv output_10.csv

一个简单的例子,但如果您知道此行为并非特定于 ls,那么您可以想象与 mvcprsync 等结合使用时的实用程序。

【讨论】:

【参考方案3】:

通配符

通过使用双星号 (**),您正在使用 glob 列出文件系统上的文件。 glob 是用于匹配文件路径的文字或通配符字符串。使用一个或多个 glob 在文件系统上定位文件称为 globbing

除了 Linux shell,globbing 还用于各种配置文件中,以指定要定位的文件列表。例如:.gitignore 文件中要忽略的文件和文件夹,Typescript 项目中tsconfig.json 文件中的filesinclude 选项等。

以下是通配符的一些最重要的方面,双星号 (**) 就是其中之一:


段和分隔符 (/)

分隔符始终是/ 字符。段是介于两个分隔符之间的所有内容。

示例:Tests/HelloWorld.js

这里,TestsHelloWorld.js 是分段,/ 是分隔符。


单个星号 (*)

单个星号 (*) 匹配 一个 段中的零个或多个字符。它用于对一个目录中的文件进行通配。

示例:*.js

此 glob 将匹配 HelloWorld.js 等文件,但不匹配 Tests/HelloWorld.jsTests/UI/HelloWorld.js 等文件


双星号 (**)

双星号 (**) 匹配 多个 段中的零个或多个字符。它用于对嵌套目录中的文件进行通配。

示例:Tests/**/*.js

在这里,文件选择将被限制在Tests 目录中。 glob 将匹配 Tests/HelloWorld.jsTests/UI/HelloWorld.jsTests/UI/Feature1/HelloWorld.js 等文件。


问号(?)

问号(?) 匹配一个段中的单个字符。当某些文件或目录的名称仅相差一个字符时,您可以使用?

示例:tests/?at.js

这将匹配tests/cat.jstest/Cat.jstest/bat.js 等文件。


方括号 ([abc])

方括号 ([...]) 使用方括号中提到的单个字符对文件进行全局化。

示例:tests/[CB]at.js

此 glob 将匹配 tests/Cat.jstests/Bat.js 等文件


方括号范围 ([a-z])

方括号范围 ([a-z]),匹配范围中指定的一个字符。

示例:tests/feature[1-9]/HelloWorld.js

此 glob 将匹配 tests/feature1/HelloWorld.jstest/feature2/HelloWorld.js 等文件...直到 9


否定 (!)

否定 (!) 可用于排除某些文件。

示例 1:tests/[!C]at.js

这将排除文件tests/Cat.js,并将匹配tests/Bat.jstests/bat.jstests/cat.js等文件。

Negation 也用于数组内的配置文件中,以否定或排除某些文件。

示例 2:['Tests/**/*.js', '!Tests/UI/**']

这将排除 Tests/UI 目录中的所有文件和文件夹。


就是这样!希望对您有所帮助!

【讨论】:

注意:globstar shell 选项在最近的 bash 版本中默认禁用,因此**(双星号)与Tests/HelloWorld.js 不匹配。要启用它,请使用 shopt -s globstarshopt -u globstar 禁用。【参考方案4】:

虽然其他一个或多个答案可能是正确的,但它们有点难以理解,尤其是如果您是像我这样的视觉型人。

所以我决定提供一个直观的答案,通过测试完全确认

我创建了以下目录结构,每个级别都有两个文件“f”,一个有文件扩展名,一个没有文件扩展名,然后在 Darwin 上的 Bash 中使用以下命令测试下表标题中的所有模式启用 globstar:stat -f "%N" <pattern>

如果你是一个视觉型的人,看表格会让你更深入地理解** 的含义,而不是仅仅阅读其他书籍中的定义答案。

.
├── f
├── f.md
└── x
    ├── f
    ├── f.md
    └── y
        ├── f
        ├── f.md
        └── z
            ├── f
            └── f.md

比较 ***

* ** */ **/ **/*.* x/*.*or*/*.* x/*or*/* x/**or*/**
f
f.md
x
x/f
x/f.md
x/y
x/y/f
x/y/f.md
x/y/z
x/y/z/f
x/y/z/f.md

在树中匹配或查找文件

*.md**.md**f.mdf**.md */*.mdx/*.md**/x/*.md */*/*.mdx/*/*.md**/y/*.md */*/*/*.mdx/*/*/*.md**/z/*.md x/**/*.md **/*.md
f
f.md
x
x/f
x/f.md
x/y
x/y/f
x/y/f.md
x/y/z
x/y/z/f
x/y/z/f.md

请注意,在 ** 之前或附加 / 以外的任何内容时,它的作用与 * 相同,如上所示 **.md**f.md,两者都不匹配 x/y/f.md例子。

【讨论】:

如果文件夹名称中有星号呢? @pablete: * 还涵盖名称中带有星号的文件。如果你想选择这样的文件,你可以使用ls *'*'*(只需在星号周围加上引号)

以上是关于双星号 (**) 通配符是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

servlet 映射 url 模式上的双通配符 (*) 是啥意思?

wildcard characters是啥意思

数据库中like\'_a%\'是啥意思

wildcard是啥意思

在python中,双星后跟变量名是啥意思? [复制]

星号 * 在 Python 中是啥意思? [复制]