long/path/**/^*.(complex|pattern)~long/path/(bad-1|bad-2)/*(.) long/path/ を繰り返さずに短いものと同じですか?

long/path/**/^*.(complex|pattern)~long/path/(bad-1|bad-2)/*(.) long/path/ を繰り返さずに短いものと同じですか?

これは zsh 拡張グローブパターンです。要点は、特定の下位層を除いて、ディレクトリ階層の下のすべてのファイルをパターンと一致させることです。タイトルのパターンは機能しますが、繰り返す必要はありませんlong/path/

私は以下を試しました:

long/path/(^(bad-1|bad-2)/|)**/^*.(complex|pattern)(.)
long/path/(**~(bad-1|bad-2)/*)/^*.(complex|pattern)(.)

次に追加KSH_GLOB:

long/path/?(^(bad-1|bad-2)/)**/^*.(complex|pattern)(.)

すべて無効なモードエラーにつながります。問題は/括弧内にあるようです。文書には次のように記載されています。

上記のように、ディレクトリ区切り文字として使用される "/"は括弧内に表示されない場合があります。

(dir/)#これはとても良いパターンなので、私を混乱させます。文書には次の内容も記載されています。

「(foo /)#」形式のパス名コンポーネントは、fooパターンに一致する0つ以上のディレクトリで構成されたパスと一致します。

これは例外だと思います。

明らかに言えば、私は同等のものを探しています。これには次のものは含まれません。

long/path/^(bad-1|bad-2)/**/^*.(complex|pattern)(.)

long/path/good.pattern、等を除くためです。

long/path/(^(bad-1|bad-2)/)#/^*.(complex|pattern)(.)
long/path/**/^*.(complex|pattern)~*/(bad-1|bad-2)/*(.)

なぜなら、これらは次のものを除外するからですlong/path/good/bad-1

編集:ところで、ソリューションで必ずしもワイルドカードを使用する必要はありません。中かっこ、履歴拡張、または他のzshツールを追加して実行できる場合は良いでしょう。

編集2:私の考えに基づいて履歴を拡張しようとしました。

long/path/**/^*.(complex|pattern)~!{#$:s/\**//}/(bad-1|bad-2)/*(.)

ただし、これは1)現在の行の最後の単語が拡張のある行の前の単語であり、2)グローバル拡張の後に履歴置換が実行されるように見えるため、失敗します。おそらくすべての拡張はそのまま実行されます。

私も中かっこを拡張しようとしました。

( IFS=\~; printf "%s\n" long/path/{**/^*.(complex|pattern),(bad-1|bad-2)/*(.)} )

動作しません。 2つのglobパターンはまだ単一のパターンでリンクされておらず、別々の単語として扱われます。IFSここではそれが考慮されていないようです。言葉になりますね。

また、グローバル修飾子で置き換えを試みました。

+/**/^*.(complex|pattern)~+/(bad-1|bad-2)/*(.:s,+,long/path,)

しかし、もちろん、交換は試合前ではなく試合後に行われるため、これは効果がありません。

答え1

わかりました!二重スラッシュタグプレフィックス:

long/path//**/^*.(complex|pattern)~*//(bad-1|bad-2)/*(.)

時には目的が見つかるまで機能が何であるか気付かないことがあります。連続スラッシュが1に等しいという事実は、実際にはそれほど役に立つかもしれないという事実を信じることができません。 :)

答え2

(...)/例外として使用される文書のリスト:

グループ化は複数のディレクトリに拡張できません。グループ内に「/」があるとエラーが発生します(ファイル名の生成に使用されるパターンにのみ適用されます)。 1つの例外があります。フルパスセグメントとして表示される(pat /)#フォーマットセットは、ディレクトリ範囲と一致することがあります。

それ以外の場合は、式を使用して結果をフィルタリングして重複を回避できます。

% print -l a/**/*(.)
a/b/c/foo/file
a/b/d/foo/file
a/bad/e/foo/file
a/nope/d/foo/file
% print -l a/**/*(.e:'[[ $REPLY != *(bad|nope)* ]]':)
a/b/c/foo/file
a/b/d/foo/file

関連情報