web-dev-qa-db-ja.com

find -name "* .xyz" -o -name "* .abc" -exec最後に指定されたサフィックスだけでなく、見つかったすべてのファイルで実行

私は走ろうとしています

find ./ -name "*.xyz" -o -name "*.abc" -exec cp {} /path/i/want/to/copy/to

実際には、これは名前の拡張子のより大きなリストですが、この例にとって重要なことはわかりません。基本的に、見つかったすべてのものを別の/ path/i/want/to/copy/toにコピーします。ただし、リストの最後の名前テストのみを実行しているようです。

-exec部分を削除すると、検出されると予想されるすべてのファイルのバリエーションが出力されます。

見つかったすべてのファイルを-execに渡すにはどうすればよいですか?

40
atxdba

findは、式全体の真理値(trueまたはfalse)を判別できるまで、指定した式を評価することにより機能します。あなたの場合、デフォルトでは式をANDで結合するため、基本的に次のことを実行しています。

-name "*.xyz" OR ( -name "*.abc" AND -exec ... )

クォートのmanページ:

GNU findは、結果が判明するまで(左辺がfalseで演算が行われるまで)優先順位の規則(セクションOPERATORSを参照)に従って、与えられた式を左から右に評価することにより、与えられた各ファイル名をルートとするディレクトリツリーを検索します。 or)の場合はtrueで、その時点でfindは次のファイル名に移動します。

つまり、名前が*.xyzに一致する場合は、後者の-name testまたは-execが既にtrueであるため、チェックすることさえしません。

あなたがしたいのは、括弧で行うことができる優先順位を強制することです。迷惑なことに、バックスラッシュを使用してシェルでエスケープする必要もあります。

find ./ \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
54
Dan Fego

Jaypalのソリューションよりも使いやすいものは次のとおりです。

   find ./ -regex ".*\.\(jpg\|png\)" -exec cp {} /path/to
16
user unknown
find . \( -name "*.xyz" -o -name "*.abc" \) -exec cp {} /path/i/want/to/copy/to \;
8
Rob Wouters