在 Java7 中,sun.nio.fs.Globs
似乎getPathMatcher()
将成语理解**
为一种跨目录边界匹配零个或多个字符的方法(请参阅getPathMatcher javadoc)。
我可以发誓一些适当的选项设置的shell(zsh,bash,tcsh)在某些时候给了我相同的行为。但是对于我的一生,我不记得如何启用它,我什至开始怀疑我的记忆是否我在某个时候工作过......(编辑:zsh 提供了这种行为,但仅适用于目录,即"**.gz"
不'不匹配foo/bar/fubar.gz
,但"**/*.gz"
确实如此)。
事实上,查看各种 glob 实现的文档(例如 POSIX glob(3)、glob(7) 和 Perl 的 File::Glob)似乎并没有在任何地方提到这种行为。一个例外是 RubyDir.glob()
显式处理**
.
(最初的问题是:“有人知道如何在 unix shell(例如 zsh)中启用此行为吗?”,但现在请参阅下面的已编辑问题)。
作为一个额外的问题:有人知道如何'**'
在 Google 中搜索吗?...
已编辑的问题
事实上,我的 shell 似乎确实接受了这种行为zsh
(感谢断言这一事实并促使我进一步研究的响应)。我认为它不匹配的原因来自以下微妙之处:"**.gz"
不会匹配 a <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)
因为我需要跨平台的东西)。