4

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)

4

2 に答える 2

5
于 2012-08-15T18:51:40.247 に答える
4

**(*/)#は、Zsh 固有の C コードで実装されている Zsh の拡張グロブ構文で (0 個以上のディレクトリ)として解釈されます ( Src/glob.c)。この動作はオプションではありません。

が Bash で有効になっている場合shopt -s globstar、Bash 固有の C コードで実装されている Bash の拡張グロブ構文で同様に動作します ( pathexp.c)。デフォルトではオフになっています。

従来の UNIXglobでは、**は と同じように解釈され*ます。

于 2012-08-15T18:54:28.997 に答える