.whl で終わるファイルのみを探す

.whl で終わるファイルのみを探す

.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括弧の拡張はワイルドカードの前に行われます(そして他のすべての形式の拡張(引数拡張を含む)の前にもこれがbashandの内容を出力する唯一のシェルであることを確認してください)。echo $P{S1,ATH}$PS1$PATH

ls -l /python/*.{whl,}

同じです:

ls -l /python/*.whl /python/*.

そして、bashBourneシェルから継承されたバグ機能は、一致しないglobが文字通りコマンドに渡されるということです。したがって、/python名前がfilenameで終わる隠しファイルでない場合、ファイル名が渡され、.そのファイルについて文句が言われます(例えば)、これはUnixでは完全に真実です。有効なファイル名)が存在しません。とオプションを使用すると、この動作が変わります。/python/*.lsls*.failglobnullglob

これで支柱の拡張は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/*.zshcshset -o cshnullglobset +o nomatchbashzshshopt -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/*.するように引数を渡します。lscsh

{x,y}しかし、厳密に言えば、ワイルドカードではなくてもすでに完了しているからです。横にワイルドカードで、中括弧全体で完成したワイルドカードがファイルと一致しない場合にのみ、コマンドはキャンセルされます。ファイル*.whl*.ファイルもない場合、エラーは次のようになります。

fish: No matches for wildcard “/python/*.{whl,}”. See `help expand`.
ls -l /python/*.{whl,}
      ^

つまり、全体/python/*.{whl,}が考慮されます。ワイルドカードここでは、中かっこ拡張でワイルドカードは生成されません。

.whlor で終わるファイルをリストするには、.次のようにします。

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ファイルを最初にリストしたい場合を除き、lsasコマンドの場合はlsリストをソートする方法に違いはありません)。

ただし、Bourneシェルのバグ機能のためにパターンに一致するファイルがない場合kshfailglobbash*.?(whl)

zshエラーとして処理せずにファイルを一覧表示したい場合(/などの2つのリストのいずれかが空の場合)、これをローカルで使用できます。*.whl*.cshfishcshnullglob

(){ 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
)

関連情報