次の2つのコードが期待どおりに機能するのはなぜですか?
ls -d .[!.]?*
echo [D]*
しかし、次の2つはそうではありません。
ls -d [.][!.]?*
echo [D]
最初のコマンドでエラーが発生します。
ls: cannot access [.][!.]*: No such file or directory
同じリストを取得しようとするとls -d .[!.]?*
。 2番目の出力は次のとおりです。
[D]
同様のエラーの説明を期待したときNo such file or directory
。私は何を見逃していますか?上記の2番目の例のセットに示されているワイルドカード要素が式を削除しない場合、式をワイルドカードにするのは正確に何ですか?
言う(コメントにもあります):
ワイルドカードは を[D]*
出力するだけでなく、…D
なども出力します。ところでDというファイルがある時もあっていない時も試してみました。ファイルが存在する場合、出力は機能しますが、ファイルが存在しない場合でも出力を取得します。理由がわからない。ディレクトリにファイルがある場合、式[D]がワイルドカードから非ワイルドカードに変更されるのはなぜですか?Desktop
Downloads
echo [D]
D
[D]
ベストアンサー1
デフォルトでは、bash(シェル)は、ドットが明示的に指定されていない限り、ドット(隠しファイルと見なされる)で始まるファイル名を拡張しません。[.]
これはリテラル文字ではなくパターンなので、隠されたファイルの表示をトリガーしないため、ls -d [.][!.]?*
どんなものとも一致しません。
shopt -s dotglob
ファイル名パターンを拡張するとき(「globbing」と呼ばれる)、常に隠しファイルを含めるようにオプションを設定することで、このデフォルトの動作を変更できます。
はい(行の先頭のドル記号はシェルプロンプトを表します。入力しないでください):
$ touch .foo
$ ls -d .[!.]?*
.foo
$ ls -d [.][!.]?*
ls: cannot access [.][!.]?*: No such file or directory
$ shopt -s dotglob
$ ls -d [.][!.]?*
.foo
問題は、echo [D]
ファイル名が一致しないと拡張が行われないことです。D
試してもファイルを指定しなかったため、echo
実際に入力した内容が提供され、エコーされます。
ファイル名が一致する場合にのみパス名拡張が発生する例:
$ touch apple
$ echo a*
apple
$ rm apple
$ echo a*
a*
一致するファイルをすべて削除した[D]*
場合。echo [D]*
[D]*