web-dev-qa-db-ja.com

再帰的なグロブ?

私はこのようなものを書きたいと思います:

$ ls **.py

すべての.pyファイル名を取得するには、ディレクトリ階層を再帰的にたどります。

検索する.pyファイルがある場合でも、シェル(bash)は次の出力を提供します。

ls: cannot access **.py: No such file or directory

私がやりたいことをする方法はありますか?

編集:lsの特定のケースに興味がないことを指定したいのですが、問題はglob構文についてです。

93
Paolo

Bashで再帰的なグロブを実行するには、bashバージョン4以降のglobstar機能が必要です。

Bashのマンページから:

globstar
    If set, the pattern ** used in a pathname expansion context will
    match all files and zero or more directories and subdirectories.
    If the pattern is followed by a /, only directories and
    subdirectories match.

あなたのパターン例について:

shopt -s globstar
ls **/*.py
116
jordanm
find . -name '*.py'

**は1つ以上のものを実行しません*、どちらも現在のディレクトリで動作します

12
doneal24

Bash 4以降(zshも含む) 新しいグロビングオプションglobstar)が追加され、設定時にパターン**を異なる方法で処理します。

ワイルドカードパターンに一致し、コマンドのワイルドカードパターンを一致した項目で置き換えることにより、一致するファイルとディレクトリの名前を返します。

通常、**を使用すると、*と同様に機能しますが、すべてのディレクトリを再帰的に(ループのように)再帰します。

有効になっているかどうかを確認するには、shopt globstarで確認してください(スクリプトでは、shopt -q globstarを使用します)。

**.pyは、再帰可能なディレクトリのリストを返さないため、現在のディレクトリでのみ機能します。そのため、複数のディレクトリレベルのワイルドカード**/*.pyを使用して、より深く行きます。

すべてのファイルを再帰的に見つけるために行った SOで検索 いくつかの構文テストを行ってください。

9
kenorb