web-dev-qa-db-ja.com

「.git」dirを見つけますが、いくつかのパスは無視してください。または `find-not`はどのように機能しますか

検索がどのように機能しないのか理解できません。

ツリー内のすべての.gitdirを見つけたいとしましょう。

find -type d -iname .git

問題ありませんが、含まれたくないdirがいくつかあるとしましょう。問題は、「古い」および「バックアップ」と呼ぶことができます。

Grep -vにパイプすることができ、それは問題なく機能します。

find -type d -iname .git | grep -v old | grep -v backup

しかし、manページを閲覧して見つけたところ、-notがあることに気づきましたが、それがどのように機能するのか理解できません。

私はこのように試しましたが、彼は古いディレクトリを除外していません。

find -type d -iname .git -not -iname old 

検索はどのように機能しませんか?この問題の発見に使用できますか?

4
Johan

findには、このケースに対処するための少し洗練された機能があります。

式に-Prune以外のアクションが含まれていない場合、式がtrueであるすべてのファイルに対して-printが実行されます。

したがって、必要な部分だけを明示的に印刷します。

find -type d \( -iname old -Prune -o -iname backup -Prune -o -iname .git -print \)

古いツリーとバックアップツリーの検索をまったく回避します。

2
jthill

find-Pruneオプションが必要です。これは非常に注意が必要です。 -pathの代わりに-nameも使用する必要があります。

私はあなたがこれを使いたいと思います:

find . -type d \( -path '*/old' -Prune -o -iname '.git' -print \)

-notの効果はによって実装されます

  • 古い「古い」と一致し、何もしない
  • または(オプション-oを使用)
  • 「.git」と一致し、名前を出力します
  • または(デフォルトで)
  • 何もしません(-printがすでに使用されている場合、findの通常のデフォルトアクションであるコマンドラインの最後の暗黙的な-printは無効になっているため)

他のバリアントは、コマンドラインではlookingより複雑ですが、たとえば、異なる論理式の使用やデフォルトのアクションの変更などにより、使いやすい場合があることを認識しています。
一方、-Pruneを含むバリアントは、読むのに時間がかかりすぎるという理由だけで他の構文を処理するのが難しい、より複雑なケースに一般化するのが簡単です。

2
Volker Siegel

-pathを指定すると、ディレクトリを除外できます。

find . -type d \( -iname .git ! -path "*/old/*" ! -path "*/backup/*" \)

-not in GNU find!と同じですが、POSIXに準拠していないことに注意してください。

man findからの引用:

   ! expr True  if  expr  is false.  This character will also usually need
          protection from interpretation by the Shell.

   -not expr
          Same as ! expr, but not POSIX compliant.
2
devnull
find -type d -iname .git -not -iname old 

これは、.gitと呼ばれ、oldとは呼ばれないディレクトリと一致します。 .gitというディレクトリはoldとは呼べないので、コマンドの意味を変えずに-not -iname oldの部分を削除できます。

-notは「一致しない」と言っていますが、「再発しない」とは言っていません。 「再発しない」という別の言い方があります。それは-Pruneと呼ばれるアクションです。次のコマンドは、「すべてのディレクトリを再帰的にトラバースしますが(find)、old-iname old -Prune)というディレクトリで停止し、.gitというディレクトリを出力します」という意味です。

find -iname old -Prune -o -type d -iname .git -print

これは( -iname old -Prune ) -o ( -type d -iname .git -print )として解析されます。検索は、-iname oldまたは(-o-type d -iname .gitの条件を満たすファイルを探すように指示されます。ファイルが最初の条件を満たすと、アクション-Prune(トラバースされたツリーから削除する、つまり再帰しない)が実行されます。ファイルが2番目の条件を満たすと、アクション-printが実行されます。印刷がデフォルトのアクションであるため、-printを省略できます。