次のディレクトリ構造があるとします。
% 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