在Java7中,
我可以发誓,在某些合适的选项设置下,某些外壳(zsh、bash、tcsh)曾经给我提供过相同的行为。但是我无论如何也想不起来如何启用这个功能,我甚至开始怀疑自己是否在某个时候让它工作......(编辑:zsh提供了这种行为,但只针对目录,即
事实上,在查看各种glob实现(例如POSIX glob(3)、glob(7)和Perl File :: Glob的文档)时,似乎没有提到这种行为。一个例外是Ruby的
(原问题是:“有人知道如何在Unix shell(例如zsh)中启用此功能吗?”,但现在请参见下面的编辑问题)。
作为一个额外的问题:有人知道如何在Google中搜索
编辑的问题 事实上,看起来我的
现在,将其与Java行为进行比较:
sun.nio.fs.Globs
和getPathMatcher()
似乎理解成语法**
作为跨目录匹配零或多个字符的一种方式(参见getPathMatcher javadoc)。我可以发誓,在某些合适的选项设置下,某些外壳(zsh、bash、tcsh)曾经给我提供过相同的行为。但是我无论如何也想不起来如何启用这个功能,我甚至开始怀疑自己是否在某个时候让它工作......(编辑:zsh提供了这种行为,但只针对目录,即
"**.gz"
不能匹配foo / bar/fubar.gz
,但"**/*.gz"
可以)。事实上,在查看各种glob实现(例如POSIX glob(3)、glob(7)和Perl File :: Glob的文档)时,似乎没有提到这种行为。一个例外是Ruby的
Dir.glob()
,它明确地处理**
。(原问题是:“有人知道如何在Unix shell(例如zsh)中启用此功能吗?”,但现在请参见下面的编辑问题)。
作为一个额外的问题:有人知道如何在Google中搜索
'**'
吗?...
编辑的问题 事实上,看起来我的
zsh
shell确实接受了这种行为(感谢回复者断言这一事实并促使我进一步查看)。我认为它不是因为以下微妙之处:"**.gz"
不能匹配<path>/<prefix>.gz
,但"**/*.gz"
可以。以下是一个示例。让我们从以下树开始:$ find . -type f | sort
./foo/a.gz
./foo/bar/fubar/abc.gz
./foo/bar/x.gz
./foo/bar/y.gz
./xyz.gz
"**.gz"
不匹配子目录中的内容,只匹配 "*.gz"
的内容:
$ ls -1 **.gz
xyz.gz
而"**/*.gz"
则表示:
$ ls -1 **/*.gz
foo/a.gz
foo/bar/fubar/abc.gz
foo/bar/x.gz
foo/bar/y.gz
xyz.gz
现在,将其与Java行为进行比较:
@Test
public void testStar() {
String pat = Globs.toUnixRegexPattern("*.gz");
assertEquals("^[^/]*\\.gz$", pat);
}
@Test
public void testStarStar() {
// '**' allows any number of directories on the path
// this apparently is not POSIX, although darn useful
String pat = Globs.toUnixRegexPattern("**.gz");
assertEquals("^.*\\.gz$", pat);
}
很明显(从正则表达式中可以看出),这里的"**"
匹配路径上的任何字符(即在正则表达式中变成".*"
),无论是在子目录中还是不在,也无论是作为文件名的一部分还是不是。
(免责声明: Globs
是sun.nio.fs.Globs.toUnixRegexPattern(String glob)
的一个副本,因为我需要一个跨平台的解决方案)。
**
递归通配符功能。据我所知,默认情况下已启用该功能。您需要使用setopt extendedglob
来打开一些额外的通配符功能,但这不是其中之一。 - Alan Curryecho *.png | wc -w
和echo **.png | wc -w
给出相同的结果。我尝试了extendedglob,但正如你所提到的,它并没有影响行为。 - Pierre D**
匹配任意数量的目录,但要匹配末尾的文件,您必须单独指定它。echo **/*.png
- Alan Curry