検索でディレクトリを除外する

検索でディレクトリを除外する

find使用するたびに、私にとっては常に完全な謎です。/mnt検索から下にあるすべてのものを除外したいのですが (私は WSL 上の Ubuntu 20.04 の bash を使用しているため、Windows スペースで検索したくありません)、findそれらのディレクトリに誤って入り込んで完全に無視されてしまいます。このページから構文を見つけました。https://stackoverflow.com/questions/4210042/how-to-exclude-a-directory-in-find-commandあらゆるバリエーションを試しましたが、すべて失敗しました。

sudo find / -name 'git-credential-manager*' -not -path '/mnt/*'
sudo find / -name 'git-credential-manager*' ! -path '/mnt/*'
sudo find / -name 'git-credential-manager*' ! -path '*/mnt/*'

これを実行すると、ただ失敗して/mntエラーが発生します (上記の構文は明確に見え、stackoverflow ページの構文は正しいように見えるため、これは本当にイライラします)。

find: ‘/mnt/d/$RECYCLE.BIN/New folder’: Permission denied
find: ‘/mnt/d/$RECYCLE.BIN/S-1-5-18’: Permission denied

findディレクトリ除外スイッチを無視しないようにする方法を教えていただけますか?

答え1

Find は-pathパスを除外しません。つまり、「このパスに一致する名前を持つ一致を報告しない」という意味です。それでもディレクトリまで降りて検索します。必要なのは次のようになります-prune(from man find):

       -prune True;  if  the file is a directory, do not descend into it.  If
              -depth is given, then -prune has no  effect.   Because  -delete
              implies  -depth, you cannot usefully use -prune and -delete to‐
              gether.  For example, to skip the directory src/emacs  and  all
              files  and  directories  under  it,  and print the names of the
              other files found, do something like this:
                  find . -path ./src/emacs -prune -o -print

あなたが望んでいるのは:

sudo find / -path '/mnt/*' -prune -name 'git-credential-manager*' 

ただし、除外しようとしているものによっては、-mount(GNU find) または-xdev(その他) を使用する方が簡単な場合があります。

からman find

-mount-xdev他のファイルシステム上のディレクトリを下りません。findの他のバージョンとの互換性を保つための の別名です。

それで:

sudo find / -mount -name 'git-credential-manager*' 

答え2

オプションは無視されません。-path述語は遭遇するすべてのファイルに対して評価され、そのツリー内のファイルに対しては単に失敗します。これは、 がディレクトリ ツリーをたどる方法には影響しません。また、の外側にあるすべてのものに一致するだけでなく、 内にあるファイルにも一致するwhichfindのようなものを作成できます。find . ! -path "./foo/*" -o -name '*.txt'foo*.txt

GNU マニュアルページここで何をすべきかは明確に示されているので、-prune代わりに以下を使用してください。

-path pattern
... ディレクトリ ツリー全体を無視するには、-pruneツリー内のすべてのファイルをチェックするのではなく、を使用します。たとえば、ディレクトリsrc/emacsとその下にあるすべてのファイルとディレクトリをスキップし、見つかった他のファイルの名前を出力するには、次のようにします。

find . -path ./src/emacs -prune -o -print

関連情報