.whl
以下のようにすべてのファイルをキャプチャしようとしています。
ls -l /python/*.{whl,}
ls: cannot access /python/*.: No such file or directory
-rw-r--r-- 1 root root 23000 Jun 14 11:02 /python/argparse-1.4.0-py2.py3-none-any.whl
-rw-r--r-- 1 root root 154423 Jun 14 11:02 /python/certifi-2019.9.11-py2.py3-none-any.whl
-rw-r--r-- 1 root root 387834 Jun 14 11:02 /python/cffi-1.14.0-cp27-cp27mu-manylinux1_x86_64.whl
-rw-r--r-- 1 root root 133356 Jun 14 11:02 /python/chardet-3.0.4-py2.py3-none-any.whl
-rw-r--r-- 1 root root 2728298 Jun 14 11:02 /python/cryptography-2.9.2-cp27-cp27mu-manylinux1_x86_64.whl
-rw-r--r-- 1 root root 11223 Jun 14 11:02 /python/enum34-1.1.10-py2-none-any.whl
-rw-r--r-- 1 root root 58594 Jun 14 11:02 /python/idna-2.8-py2.py3-none-any.whl
-rw-r--r-- 1 root root 18159 Jun 14 11:02 /python/ipaddress-1.0.23-py2.py3-none-any.whl
-rw-r--r-- 1 root root 125774 Jun 14 11:02 /python/Jinja2-2.11.2-py2.py3-none-any.whl
しかし、見てわかるように、私たちはまた次のようになります。ls: cannot access /python/*.: No such file or directory
. で終わるファイルのみを見つけるには、この問題を解決するにはどうすればよいですか?whl
答え1
whl
拡張子を持つファイルにのみ興味がある場合
ls -l /python/*.whl
それはあなたが望むものです。
現在のコマンド、
ls -l /python/*.{whl,}
等しい
ls -l /python/*.whl /python/*.
(ありがとうございます。支柱の拡張)後者のパターンがのどれとも一致しないため失敗します/python
。
答え2
〜のように@StephenKittが言った。中bash
括弧の拡張はワイルドカードの前に行われます(そして他のすべての形式の拡張(引数拡張を含む)の前にもこれがbash
andの内容を出力する唯一のシェルであることを確認してください)。echo $P{S1,ATH}
$PS1
$PATH
ls -l /python/*.{whl,}
同じです:
ls -l /python/*.whl /python/*.
そして、bash
Bourneシェルから継承されたバグ機能は、一致しないglobが文字通りコマンドに渡されるということです。したがって、/python
名前がfilenameで終わる隠しファイルでない場合、ファイル名が渡され、.
そのファイルについて文句が言われます(例えば)、これはUnixでは完全に真実です。有効なファイル名)が存在しません。とオプションを使用すると、この動作が変わります。/python/*.
ls
ls
*.
failglob
nullglob
これで支柱の拡張は1970年代後半のcshから来ました。では、エラーが表示されないことがわかりますcsh
。
csh
初期 Unices (名前は glob) のように動作する Bourne シェルの欠陥がなければ/etc/glob
、一致しない glob は (現状のまま渡されず) 削除されます。みんなコマンドラインのglobを一致させることができず、コマンドはキャンセルされました(明らかに何かが間違っているので合理的なアクションです)。
だからcsh
:
ls -l /python/*.{whl,}
まず、次に展開してください。
ls -l /python/*.whl /python/*.
inに似ていますbash
が、/python/*.
一致するファイルは/python/*.whl
ありませんが、一部ファイルは/python/*.
削除され、ls
ファイルリストを使用して呼び出されます.whl
。
ファイルが存在しない場合、エラーが.whl
発生します。No match
非悪市、エラーの代わりに渡すls
存在しないファイルについて。
zsh
コピー中括弧で拡張される別のシェルですcsh
。一致しない地球の動作は異なります。
zsh
また、Bourne シェルの欠陥はありませんが(少なくともデフォルトではありません)、次の場合はコマンドをキャンセルします。どの(大みんなcsh
/)glob/etc/glob
は一致しないため、ls -l /python/*.{whl,}
ファイルがあってもls -l /python/*.whl /python/*.
globが一致しないため実行されません。では、を使用してアクションを取得するか、またはを使用してBourneアクション(推奨されていません)を取得できます。ではwithと同様の動作を得ることができます。ls
.whl
/python/*.
zsh
csh
set -o cshnullglob
set +o nomatch
bash
zsh
shopt -s failglob
シェルはfish
異なる動作をします。
fish
(最新のシェル)は、zsh
失敗したglobキャンセルコマンドのように動作します。のようにzsh
、あなたは見ることができます
ls -l /python/*.whl /python/*.
実行されず、ls
次を返します。
fish: No matches for wildcard “/python/*.”. See `help expand`.
ls -l /python/*.whl /python/*.
^
間違い。しかし、
ls -l /python/*.{whl,}
するいいえエラーの返却、.whl
ファイルの一覧表示、実行いいえこのように動作/python/*.
するように引数を渡します。ls
csh
{x,y}
しかし、厳密に言えば、ワイルドカードではなくてもすでに完了しているからです。横にワイルドカードで、中括弧全体で完成したワイルドカードがファイルと一致しない場合にのみ、コマンドはキャンセルされます。ファイル*.whl
も*.
ファイルもない場合、エラーは次のようになります。
fish: No matches for wildcard “/python/*.{whl,}”. See `help expand`.
ls -l /python/*.{whl,}
^
つまり、全体/python/*.{whl,}
が考慮されます。ワイルドカードここでは、中かっこ拡張でワイルドカードは生成されません。
.whl
or で終わるファイルをリストするには、.
次のようにします。
ls -ld /python/*(.|.whl) # zsh
ls -ld /python/*.(|whl) # zsh
ls -ld /python/*@(.|.whl) # ksh / bash -O extglob
ls -ld /python/*.?(whl) # ksh / bash -O extglob
つまり、グローバルオペレータ以内に一つ2つのglobではなく、それぞれの場合に1つずつ、2つのglobと一致します(.whl
ファイルを最初にリストしたい場合を除き、ls
asコマンドの場合はls
リストをソートする方法に違いはありません)。
ただし、Bourneシェルのバグ機能のためにパターンに一致するファイルがない場合ksh
。failglob
bash
*.?(whl)
zsh
エラーとして処理せずにファイルを一覧表示したい場合(/などの2つのリストのいずれかが空の場合)、これをローカルで使用できます。*.whl
*.
csh
fish
cshnullglob
(){ set -o localoptions -o cshnullglob; ls -ldU /python/*.{whl,}; }
(これはGNUを仮定し、ls
その-U
オプションを使用してソートを無効にします)。
またはN
、glob修飾子を使用して(nullglob
アクションのインポート)、手動でエラー処理を実行します(両方のglobが一致しない場合)。
() {
if (($#)); then
ls -ldU -- "$@"
else
echo>&2 No match
return 1
fi
} /python/*.{whl,}
bash
オプションと位置引数の範囲を制限するために(匿名関数がないため)、サブシェルを使用してbashで同様の操作を実行できます。
(
shopt -s nullglob
shopt -u failglob # failglob takes precedence over nullglob when set!
set -- /python/*.{whl,}
if (($#)); then
ls -ldU -- "$@"
else
echo>&2 No match
exit 1
fi
)