ファイルが見つかったら、検索ツリーのクリーンアップ

ファイルが見つかったら、検索ツリーのクリーンアップ

名前が特定のファイル名ワイルドカードパターンと一致する一般的なファイルを見つけるには、かなり大きなディレクトリ階層を検索する必要があります。階層が大きすぎて(非常に深くて巨大なディレクトリがある)、単純なアプローチでは時間がかかりすぎます。

find /top/dir -type f -name 'pattern'

pattern類似パターンはどこにありますか*proj*.tgz?)

ディレクトリ構造の性質のためにfindディレクトリにファイルが見つかった場合は、検索ツリーをクリーンアップするために最適化を導入できることがわかります。たとえば、特定のディレクトリで1つ以上のファイルを見つけることは、その特定のディレクトリのサブディレクトリで他の一致を確認する必要がないことを意味します。

通常のファイルに適用するのが正しくないため、-pruneこれはできません。

find /top/dir -type f -name 'pattern' -prune

質問:パターンに一致するファイルを含むディレクトリのサブディレクトリ検索を防ぐにはどうすればよいですか?

ベストアンサー1

各ディレクトリに対してインラインスクリプトを呼び出すことができます。スクリプトは、パターンがディレクトリの通常のファイルと一致することを確認します。パターンが一致すると、出力(通常プロセス単に印刷する代わりに、パス名を一致させ、検索ツリーで親ディレクトリをクリーンアップします。

find /top/dir -type d -exec zsh -c '
    set -- "$1"/pattern(.N)
    [[ $# -eq 0 ]] && exit 1
    printf "%s\n" "$@"' zsh {} \; -prune

インラインスクリプトのシェルを使用して、シェルのグローバル修飾zsh子にアクセスします。ここで使用される修飾子は、(.N)通常のファイルのみがパターンと一致することを確認し、一致するファイルが存在しない場合はパターンが削除されます。


bashインラインスクリプトの場合:

find /top/dir -type d -exec bash -O nullglob -c '
    unset -v found
    for pathname in "$1"/pattern; do
        if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
            printf "%s\n" "$pathname"
            found=true
        fi
    done
    "${found-false}"' bash {} \; -prune

つまり、特定のディレクトリのパターンと一致する名前を介してインラインスクリプトループを持ち、名前が通常のファイルに対応する場合はそれを処理して「フラグ」を設定します。このフラグが最後に設定されると、親ディレクトリがクリーンアップされます。

おすすめ記事