複数の「-name」と「-exec」を持つ「find」は、「-name」の最後の一致のみを実行します


74

私が使用しているとき

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"

すべての種類のファイルを検索します。しかし-exec、最後に追加すると:

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' {} \;

.txtファイルのみを印刷するようです。私は何を間違えていますか?

注:MINGW(Git Bash)の使用


ヒント:最初のコマンドは、名前がまたはに一致するディレクトリも出力します。*.js**.txt
ワイルドカード

回答:


99
見つける 。-type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt"

の略です:

見つける 。\(\(- type f -a -name "* .htm *" \)- o \
          \(- name "* .js *" \)- o \
          \(- name "* .txt" \)\
       \)-a -print

つまり、アクションの述語が指定されていないため(条件のみ)、-print条件に一致するファイルに対してアクションが暗黙的に追加されます。

(そして、ところで、それは非正規の.jsファイルを印刷するでしょう(ファイルに-type fのみ適用され.htmます))。

一方:

見つける 。-type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt" \
  -exec sh -c 'echo "$ 0"' {} \;

の略です:

見つける 。\(- type f -a -name "* .htm *" \)- o \
       \(- name "* .js *" \)- o \
       \(- name "* .txt" -a -exec sh -c 'echo "$ 0"' {} \; \)

以下のためにfind(多くの言語のように)、AND-a;省略時に暗黙的に)よりも優先しているOR-o)、および明示的なアクション述語を追加する(ここでは-exec)キャンセルする-print上で見た暗黙のアクションを。ここで、あなたが欲しい:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) \
  -exec sh -c 'echo "$0"' {} \;

または:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c '
   for i do
     echo "$i"
   done' sh {} +

shファイルごとに1つ実行することを避けるため。


これらのsh -cの使用法のいくつかでは、shのゼロ番目の引数を追加する必要があります(ただし、他の引数では既にそれを含めています)。
ジェームズヤングマン

1
それは素晴らしい答えです!
マリノス

30

それは暗黙の括弧です。明示的な括弧を追加します。\( \)

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c 'echo "$0"' {} \;

またはxargsを使用します(xargsが好きですが、簡単だと思いますが、明らかにポータブルではありません)。

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -print0 | xargs -0 -n1 echo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.