Unix通配符选择器? (星号)

22
在 Ryan Bates 的 关于 git 的 Railscast 中,他的 .gitignore 文件包含以下行:tmp/**/* 使用双星号后跟一个星号的目的是什么,例如: **/*? 使用 tmp/* 而不是 tmp/**/* 是否不能达到完全相同的效果?
通过谷歌搜索,我发现了一篇不清晰的 IBM 文章,想知道是否有人能够澄清这个问题。

注意:虽然一些shell支持这种语法,但Git不支持。在.gitignore文件中,这相当于tmp/*/* - hammar
3个回答

26

它指示要进入 tmp 目录下的所有子目录以及 tmp 目录中的所有内容。

例如,我有以下内容:

$ find tmp
tmp
tmp/a
tmp/a/b
tmp/a/b/file1
tmp/b
tmp/b/c
tmp/b/c/file2

匹配输出:

$ echo tmp/*
tmp/a tmp/b

匹配的输出:

$ echo tmp/**/*
tmp/a tmp/a/b tmp/a/b/file1 tmp/b tmp/b/c tmp/b/c/file2

这是zsh的默认功能,在bash 4中使其工作,执行以下操作:

shopt -s globstar

在Unix系统中,这种模式匹配是否有命名规则?我正在尝试寻找更多信息,但我不知道该如何在Google上搜索。 - Jondlm
文件的模式匹配被称为globbing。基本变体是*表示0个或多个字符,?表示任何字符,[CharacterRange]表示匹配特定范围的字符,例如[0-9]表示匹配数字。一些shell会以自己的方式扩展它,其中包括**语法。 - Anya Shenanigans
我在我的bash shell中尝试了一下,但是echo tmp/**/和tmp//给出了相同的结果,所以我认为**没有比更多的作用。 - Storm
创建两个以上层级的子目录,你会看到区别。 - Anya Shenanigans

6

来自http://blog.privateergroup.com/2010/03/gitignore-file-for-android-development/

(kwoods)

"The double asterisk (**) is not a git thing per say, it’s really a linux / Mac shell thing.

It would match on everything including any sub folders that had been created.

You can see the effect in the shell like so:

# ls ./tmp/* = should show you the contents of ./tmp (files and folders)
# ls ./tmp/** = same as above, but it would also go into each sub-folder and show the contents there as well."

2
根据gitignore的文档,此语法自git版本1.8.2起受支持。
以下是相关部分:
在与完整路径名匹配的模式中,连续出现的两个星号(**)可能有特殊含义:
- 以两个星号(**)和斜杠开头表示匹配所有目录。例如,**/foo 匹配任何地方的文件或目录 foo,与模式 foo 相同。**/foo/bar 匹配直接在目录 foo 下的任何地方的文件或目录 bar。 - 以斜杠结尾的 ** 匹配目录内的所有内容。例如,abc/** 匹配相对于 .gitignore 文件位置的目录 abc 中的所有文件,无限深度。 - 斜杠后跟连续两个星号然后是斜杠,匹配零个或多个目录。例如,a/**/b 匹配 a/b、a/x/b、a/x/y/b 等。 - 其他连续的星号被视为无效。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接