次のディレクトリ構造があるとします。
% tree foo
foo
├── bar
│ └── baz
└── baz
2つのエレガントなマッチング方法foo/bar/baz
そして foo/baz
?つまり、bar/
パスのコンポーネントを選択的にする方法は何ですか?
foo/*/baz
有効な拡張子ではないfoo/bar/baz
ので一致します。foo//baz
オプションのグループを試しましたが、次のようになります。
% set -o KSH_GLOB
% echo foo/?(bar)/baz
また、foo/bar/baz
同じ理由で(foo//baz
有効な拡張子ではない)に拡張されます。/
によると、グループ内にaを含めることは通常違法であるため、たとえばzshexpn(1)
エラーfoo/?(bar/)baz
が発生します。
特に奇妙なケースではないようですが、Google検索やSE検索では関連コンテンツが見つかりません。
答え1
これはkshとzsh globの問題です。中かっこを使用できます。
echo foo{,/bar}/baz
echo foo{,/*}/baz # you probably don't want this one, see below
ただし、校正器は全体ではなく、校正器が十分に近いかどうかは、実行している作業によって異なります。
主な質問は、どのファイルが存在するのか、一部のファイルが存在しない場合はどうなるのかということです。foo{,/bar}/baz
2つの単語に展開され、foo/baz
ファイルfoo/bar/baz
が存在するかどうか。ワイルドカードを使用すると、デフォルトでfoo{,/*}/baz
一致するファイルがないとエラーが発生します。存在foo/*/baz
しても同じです。foo/baz
次の方法でこの問題を解決できます。N
ワイルドカードフラグ:
echo foo{/*,}/baz(N)
これにより、一致する既存のファイルのリストfoo/*/baz
(リストが空であっても)に展開されます。これは、機能すると得られるものとfoo/baz
同じです。foo/(*/|)/baz(N)
一方、単純に同等のものはありませんfoo/(*/|)/baz
。一致するものがない場合にエラーが発生するには、自分で行う必要があります。
bazes=(foo{,/*}/baz(N))
if (($#bazes == 0)); then echo >&2 "No bazes are belong to us"; return 1; fi
中かっことglobのもう1つの違いは、中かっこ内の順序によって拡張順序が決定されることです。たとえば、編集時間に関係なく、echo foo{,/*}/baz(Nom)
常に最初に入力します。foo/baz
答え2
誤って> 1つの「オプションの」パス名コンポーネントを一致させた場合、問題はありません。次のことができます。
% set -o EXTENDED_GLOB
% echo foo/(bar/)#baz
foo/bar
これはとに一致しますfoo/bar/baz
が、foo/bar/bar/baz
等とも一致します。
答え3
両方の場所で一致するファイルが必要かどうか明示的に話していません。ただまたはみんな彼らは木にあります。すべての項目を一致させるオプションがある場合は、次のものを使用できます**
。
% mkdir -p foo/{bar,asdf/asdf,}/baz
% echo foo/**/baz
foo/asdf/asdf/baz foo/bar/baz foo/baz
Bashでも動作します(globstar
有効)。
$ shopt -s globstar
$ echo foo/**/baz
foo/asdf/asdf/baz foo/bar/baz foo/baz
(zshとBashの間にはいくつかの注意点/違いがあります**
。ツリーのシンボリックリンクです。)