在Java7中,sun.nio.fs.Globs
和getPathMatcher()
似乎将习语**
理解为跨目录边界匹配零个或多个字符的方式(请参阅{{ 3}})。
我可以发誓一些shell(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
&#34;将:
$ 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);
}
显然(来自正则表达式),这里"**"
匹配路径上的任何字符(即它在regexp中变为".*"
),无论是否在子目录中,以及作为文件名的一部分或不
(免责声明:Globs
是sun.nio.fs.Globs.toUnixRegexPattern(String glob)
的副本,因为我需要跨平台工作的内容。
答案 0 :(得分:5)
在POSIX shell中:
路径名中的斜杠字符应使用明确匹配 图案中有一个或多个斜杠;它不应该被匹配 星号或问号特殊字符也不用括号 表达
你可以谷歌:“文件名扩展模式”。
在bash中,您可以设置globstar
:
[星号]匹配任何字符串,包括空字符串。当globstar shell 选项已启用,
‘*’
用于文件名扩展上下文, 用作单个模式的两个相邻‘*’
将匹配所有文件和 零个或多个目录和子目录。如果后跟一个'/',两个 相邻‘*’
s只匹配目录和子目录。
$ shopt -s globstar
$ ls **/
$ shopt -u globstar
$ ls **/
注意:此处使用'/'仅显示目录。
答案 1 :(得分:3)
**
在Zsh的扩展glob语法中被解释为(*/)#
(零个或多个目录),该语法在Zsh特定的C代码(Src/glob.c
)中实现。此行为不是可选的。
在Bash中启用shopt -s globstar
时,它在Bash的扩展glob语法中的行为类似,它以Bash特定的C代码(pathexp.c
)实现。默认情况下这是关闭的。
在传统的UNIX glob
中,**
的解释与*
相同。