findのprune's -pathにはワイルドカードは含まれていません。

findのprune's -pathにはワイルドカードは含まれていません。

検索ツリーから特定のディレクトリを除外したいと思います。.aaa現在のディレクトリの隠しサブディレクトリです。その名前にaaa_rc_bbb, xxx_rc_xxx含まれるより多くのサブディレクトリを除外したいと思います。rcしかし、それは無視せずにrcサブディレクトリを含む結果を提供します。*rc*ワイルドカードが機能しないようです。

find -L /students/projects/myname/ -name .aaa -prune -o -path */*/class_project/*/*/pikachu/*/*/*rc*/ -prune -o -path */*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt | head -n50 | xargs ls

また、次のルートでのみ検索したいと思います。*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

助けてください。私は何が間違っていましたか?

答え1

最初の問題は、引用されていないglob()があることです*。これらのパスはすべて単一引用符で囲む必要があります(例:)'*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt'。これにより、シェルがワイルドカード文字を渡す前に拡張するのを防ぎますfind

-prune次に、基本検索サブ式の前に表示するサブ式が必要です。ちなみに、すべての名前を次の複合式にまとめることができます-prune

find \( \( -name '*foo*' -o -name '*bar*' \) -a -prune \) -o \( -name baz -a -print \)

これは、その名前を含む、または含むbazファイル/ディレクトリを除いて、指定されたファイルを探したいことを意味します。foobar

いくつかの注意:

  • 私は(AND)演算子とかっこについてはかなり自由なので、-aあいまいさはありません。
  • 括弧の目的は、優先順位を変更し、他のほとんどの式タイプと同様に、エスケープされて\渡される前にシェルで解釈されないようにすることですfind
  • 私は2つの-nameテストを使用していますが、他のテスト(例-path:)は最初の入れ子括弧内にあるかもしれません。テストに一致するファイル/ディレクトリは切り捨てられ、次のテスト(最後の括弧セット)には適用されません。
  • -print作業を部分から区別するために明示的にすることをお勧めします-prune

明確にするために、より一般的な表現スタイルで書き直しましょう。

((name=='*foo*' OR name=='*bar*') AND prune) OR (name==bar AND print)

でも

if (name=='*foo*' OR name=='*bar*')
   prune
else if (name==bar)
   print
fi

一般的な優先順位ルールとデフォルトのブール演算子が与えられたら、-a次のように単純化できます。

find \( -name '*foo*' -o -name '*bar*' \) -prune -o -name baz -print

findコマンドを実行すると、見つかったファイルに対して作成されたパスが/文字で終わらないため、-path '*/*/class_project/*/*/pikachu/*/*/*rc*/'一致できません。ファイルの種類を制限するには、その末尾を削除し、/可能であれば追加する必要があります。-type d目次

また、*/*パターンマッチングに含まれるすべての文字列にはが/含まれていますfoo/bar/baz。ここで、パスはすべてinで始まるので、inはすでにそこにあることが/students/projects/myname/わかっているので重複します。/*/*/

あなたの意図を正しく読んだ場合は、2番目のサブ式のテストを実行しません。つまり、ファイルが切り捨てられない場合は印刷しようとします。それで、これは次のように続きます。

find -L /students/projects/myname/ \
  \( \
       -name .aaa \
    -o -path '*/class_project/*/*/pikachu/*/*/*rc*' \
    -o -path '*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt' \
  \) -prune \
  -o -print

答え2

パターンは-pathスラッシュで終わります。find解決されたパス名はスラッシュで終わらないため、パターンはどんなものとも一致しません。

呼び出されたディレクトリと.aaaその名前に含まれるディレクトリをクリーンアップするには、次の手順を実行します。rc

find -L /students/projects/myname \
    -type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o -print

パスのみを表示*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

find -L /students/projects/myname \
    -type d '(' -name '.aaa' -o -name '*rc*' ')' -prune -o \
    -path '*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt' -print

bambi.txtこれは

/students/projects/myname/*/*/class_project/*/*/pikachu/*/*/bambi/b‌​ambi.txt

コマンドのパターンへの参照を参照してくださいfind。引用符がない場合、シェルは を呼び出す前にパターンをパス名のリストに拡張しようとしfindますfind

関連情報