名前が特定のファイル名ワイルドカードパターンと一致する一般的なファイルを見つけるには、かなり大きなディレクトリ階層を検索する必要があります。階層が大きすぎて(非常に深くて巨大なディレクトリがある)、単純なアプローチでは時間がかかりすぎます。
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
つまり、特定のディレクトリのパターンと一致する名前を介してインラインスクリプトループを持ち、名前が通常のファイルに対応する場合はそれを処理して「フラグ」を設定します。このフラグが最後に設定されると、親ディレクトリがクリーンアップされます。