Java7 では、sun.nio.fs.Globs
ディレクトリの境界を越えて0 個以上の文字を照合する方法としてgetPathMatcher()
イディオムを理解しているようです( getPathMatcher javadocを参照)。**
シェルのフレーバー (zsh、bash、tcsh) と適切なオプション設定を使用すると、ある時点で同じ動作が得られたと断言できます。しかし、私の人生では、これを有効にする方法を思い出せず、ある時点で機能していたという記憶を疑い始めています...(編集:zshはその動作を提供しますが、ディレクトリに対してのみ、つまりはし"**.gz"
ません一致しませんfoo/bar/fubar.gz
が、一致"**/*.gz"
します)。
実際、glob のさまざまな実装 (POSIX glob(3)、glob(7)、および Perl の File::Glob など) のドキュメントを見ると、この動作はどこにも言及されていないようです。Dir.glob()
1 つの例外は、明示的に を処理するRuby**
です。
(元の質問は、「UNIX シェル (zsh など) でこの動作を有効にする方法を知っている人はいますか?」でしたが、以下の編集済みの質問を参照してください)。
おまけの質問: Google で検索する方法を知っている人はい'**'
ますか?...
編集された質問
実際、その動作は実際に私のzsh
シェルで受け入れられているようです (その事実を主張し、さらに調べるように促した応答に感謝します)。そうではないと思った理由は、次の微妙な点から来ています: "**.gz"
will not match a <path>/<prefix>.gz
, but "**/*.gz"
will. ここに例があります。次のツリーから始めましょう。
$ 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)